From bc7a2250807fc8e37659031663554fc22be9c22c Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Tue, 20 Jul 2021 11:28:26 -0700 Subject: [PATCH] Expand 20152-local-variables test Added a compiled C implementation of strlen(). The most interesting part about this is that it references a 16-bit value via direct-page address $ff, which means you'd want a local variable with address=$ff and width=2. The current UI prevents this. --- SourceGen/MainController.cs | 11 +++ SourceGen/PlatformSymbols.cs | 2 +- SourceGen/SGTestData/20152-local-variables | Bin 151 -> 237 bytes .../SGTestData/20152-local-variables.dis65 | 81 +++++++++++++++- .../Expected/20152-local-variables_64tass.S | 59 ++++++++++++ .../Expected/20152-local-variables_acme.S | 70 ++++++++++++++ .../Expected/20152-local-variables_cc65.S | 59 ++++++++++++ .../Expected/20152-local-variables_cc65.cfg | 2 +- .../Expected/20152-local-variables_merlin32.S | 55 +++++++++++ .../SGTestData/Source/20152-local-variables.S | 88 ++++++++++++++++++ 10 files changed, 422 insertions(+), 5 deletions(-) diff --git a/SourceGen/MainController.cs b/SourceGen/MainController.cs index 12ca998..02d9c4c 100644 --- a/SourceGen/MainController.cs +++ b/SourceGen/MainController.cs @@ -1181,6 +1181,17 @@ namespace SourceGen { /// File data. private byte[] FindValidDataFile(ref string dataPathName, DisasmProject proj, out bool cancel) { + // TODO(someday): + // It would be nice to "fix" the length and CRC if they don't match while we're + // making manual edits to test files. We can pass "can fix" to the ChooseDataFile + // dialog, and have it return a "want fix" if they click on the "fix" button, and + // only enable this if the DEBUG menu is enabled. It's a little ugly but mostly + // works. One issue that must be handled is that "proj" has sized a bunch of data + // structures based on the expected file length, and will blow up if the actual + // length is different. So we really need to check both len/crc here, and if + // all broken things are fixable, return the "do fix" back to the caller so + // it can re-generate the DisasmProject object with the corrected length. + FileInfo fi = new FileInfo(dataPathName); if (!fi.Exists) { Debug.WriteLine("File '" + dataPathName + "' doesn't exist"); diff --git a/SourceGen/PlatformSymbols.cs b/SourceGen/PlatformSymbols.cs index 5f31673..65ab484 100644 --- a/SourceGen/PlatformSymbols.cs +++ b/SourceGen/PlatformSymbols.cs @@ -41,7 +41,7 @@ namespace SourceGen { /// and mask may be hex, decimal, or binary; these are simply tokenized by regex. /// /// Looks like: - /// NAME {@,=,<,>} VALUE [& MASK] [WIDTH] [;COMMENT] + /// NAME {@,=,<,>} VALUE [WIDTH] [;COMMENT] /// /// Regex output groups are: /// 1. NAME (2+ alphanumeric or underscore, cannot start with number) diff --git a/SourceGen/SGTestData/20152-local-variables b/SourceGen/SGTestData/20152-local-variables index 2e009386ec607b6ea99ad0184bfa3d057906fa57..86fec2026fe45fdfc131f357264b6eff58bae7ec 100644 GIT binary patch delta 94 zcmV-k0HObv0qp^hmRIT+`@%5v008u?03x&i066yb`04x9jV0G3m AWdHyG delta 8 PcmaFMIGu6AG{yt~4{8Gr diff --git a/SourceGen/SGTestData/20152-local-variables.dis65 b/SourceGen/SGTestData/20152-local-variables.dis65 index 66c96c5..5a2a349 100644 --- a/SourceGen/SGTestData/20152-local-variables.dis65 +++ b/SourceGen/SGTestData/20152-local-variables.dis65 @@ -1,8 +1,8 @@ ### 6502bench SourceGen dis65 v1.0 ### { "_ContentVersion":4, -"FileDataLength":151, -"FileDataCrc32":-814797830, +"FileDataLength":237, +"FileDataCrc32":1833028653, "ProjectProps":{ "CpuName":"65816", "IncludeUndocumentedInstr":false, @@ -183,6 +183,20 @@ "Value":145, "Source":"User", "Type":"LocalOrGlobalAddr", +"LabelAnno":"None"}, + +"170":{ +"Label":"STRING", +"Value":172, +"Source":"User", +"Type":"GlobalAddr", +"LabelAnno":"None"}, + +"178":{ +"Label":"STRLEN", +"Value":180, +"Source":"User", +"Type":"GlobalAddr", "LabelAnno":"None"}}, "OperandFormats":{ @@ -216,7 +230,15 @@ "Length":2, "Format":"NumericLE", "SubFormat":"Ascii", -"SymbolRef":null}}, +"SymbolRef":null}, + +"155":{ +"Length":3, +"Format":"NumericLE", +"SubFormat":"Symbol", +"SymbolRef":{ +"Label":"STRING", +"Part":"Bank"}}}, "LvTables":{ "12":{ @@ -756,6 +778,59 @@ "145":{ "Variables":[], +"ClearPrevious":false}, + +"178":{ +"Variables":[{ +"DataDescriptor":{ +"Length":2, +"Format":"NumericLE", +"SubFormat":"Hex", +"SymbolRef":null}, + +"Comment":"", +"HasWidth":true, +"Direction":"ReadWrite", +"MultiMask":null, +"Label":"LEN", +"Value":242, +"Source":"Variable", +"Type":"ExternalAddr", +"LabelAnno":"None"}, + +{ +"DataDescriptor":{ +"Length":4, +"Format":"NumericLE", +"SubFormat":"Hex", +"SymbolRef":null}, + +"Comment":"", +"HasWidth":true, +"Direction":"ReadWrite", +"MultiMask":null, +"Label":"PTR", +"Value":244, +"Source":"Variable", +"Type":"ExternalAddr", +"LabelAnno":"None"}, + +{ +"DataDescriptor":{ +"Length":3, +"Format":"NumericLE", +"SubFormat":"Hex", +"SymbolRef":null}, + +"Comment":"", +"HasWidth":true, +"Direction":"ReadWrite", +"MultiMask":null, +"Label":"ARG", +"Value":253, +"Source":"Variable", +"Type":"ExternalAddr", +"LabelAnno":"None"}], "ClearPrevious":false}}, "Visualizations":[], diff --git a/SourceGen/SGTestData/Expected/20152-local-variables_64tass.S b/SourceGen/SGTestData/Expected/20152-local-variables_64tass.S index afc5db6..89e6fe1 100644 --- a/SourceGen/SGTestData/Expected/20152-local-variables_64tass.S +++ b/SourceGen/SGTestData/Expected/20152-local-variables_64tass.S @@ -114,6 +114,65 @@ SPLITTER .var $80 _SPLIT2 lda ',' ldx $5678 beq _SPLIT2 + nop + clc + xce + rep #$30 + .al + .xl + pea STRING >> 16 + pea STRING + jsl STRLEN + sec + xce + .as + .xs + jmp L00E6 + +STRING .text "testing" + .byte $00 + +LEN .var $f2 +PTR .var $f4 +ARG .var $fd + .al + .xl +STRLEN phd + tsc + sec + sbc #$00f7 + tcd + adc #$00f0 + tcs + stz LEN +_L00C1 ldx ARG+2 + lda ARG + inc ARG + bne _L00CB + inc ARG+2 +_L00CB sta PTR + stx PTR+2 + lda [PTR] + and #$00ff + beq _L00DA + inc LEN + bra _L00C1 + +_L00DA lda LEN + tay + tdc + clc + adc #$00f7 + tcs + tya + pld + rtl + + .as + .xs +L00E6 bit ARG+2 + bit @w$00ff + bit $0100 rts .here diff --git a/SourceGen/SGTestData/Expected/20152-local-variables_acme.S b/SourceGen/SGTestData/Expected/20152-local-variables_acme.S index 228e817..2b5c8b2 100644 --- a/SourceGen/SGTestData/Expected/20152-local-variables_acme.S +++ b/SourceGen/SGTestData/Expected/20152-local-variables_acme.S @@ -224,6 +224,76 @@ DPCODE nop .SPLITTER = $80 ldx $5678 beq @SPLIT2 + nop + clc + xce + rep #$30 + !al + !rl + pea STRING >> 16 + pea STRING + jsl STRLEN + sec + xce + !as + !rs + jmp L00E6 + +STRING !text "testing" + !byte $00 + + !zone Z0000b2 +.NH0 = $00 ;not hidden +.NH1 = $01 ;not hidden +.PTR0 = $10 +.CONST0 = $10 +.PTR_C = $1d +.PTR_D = $21 +.VAL0 = $30 +.VAL14 = $31 +.VAL5 = $35 +.SPLITTER = $80 +.LEN = $f2 +.PTR = $f4 +.ARG = $fd + !al + !rl +STRLEN phd + tsc + sec + sbc #$00f7 + tcd + adc #$00f0 + tcs + stz .LEN +@L00C1 ldx .ARG+2 + lda .ARG + inc .ARG + bne @L00CB + inc .ARG+2 +@L00CB sta .PTR + stx .PTR+2 + lda [.PTR] + and #$00ff + beq @L00DA + inc .LEN + bra @L00C1 + +@L00DA lda .LEN + tay + tdc + clc + adc #$00f7 + tcs + tya + pld + rtl + + !as + !rs +L00E6 bit .ARG+2 + bit+2 $00ff + bit $0100 rts } ;!pseudopc diff --git a/SourceGen/SGTestData/Expected/20152-local-variables_cc65.S b/SourceGen/SGTestData/Expected/20152-local-variables_cc65.S index 157f2fe..697983e 100644 --- a/SourceGen/SGTestData/Expected/20152-local-variables_cc65.S +++ b/SourceGen/SGTestData/Expected/20152-local-variables_cc65.S @@ -114,5 +114,64 @@ SPLITTER .set $80 @SPLIT2: lda ',' ldx $5678 beq @SPLIT2 + nop + clc + xce + rep #$30 + .a16 + .i16 + pea STRING >> 16 + pea STRING + jsl STRLEN + sec + xce + .a8 + .i8 + jmp L00E6 + +STRING: .byte "testing" + .byte $00 + +LEN .set $f2 +PTR .set $f4 +ARG .set $fd + .a16 + .i16 +STRLEN: phd + tsc + sec + sbc #$00f7 + tcd + adc #$00f0 + tcs + stz LEN +@L00C1: ldx ARG+2 + lda ARG + inc ARG + bne @L00CB + inc ARG+2 +@L00CB: sta PTR + stx PTR+2 + lda [PTR] + and #$00ff + beq @L00DA + inc LEN + bra @L00C1 + +@L00DA: lda LEN + tay + tdc + clc + adc #$00f7 + tcs + tya + pld + rtl + + .a8 + .i8 +L00E6: bit ARG+2 + bit a:$00ff + bit $0100 rts diff --git a/SourceGen/SGTestData/Expected/20152-local-variables_cc65.cfg b/SourceGen/SGTestData/Expected/20152-local-variables_cc65.cfg index 4e4dc93..b8d33a4 100644 --- a/SourceGen/SGTestData/Expected/20152-local-variables_cc65.cfg +++ b/SourceGen/SGTestData/Expected/20152-local-variables_cc65.cfg @@ -2,7 +2,7 @@ MEMORY { MAIN: file=%O, start=%S, size=65536; # MEM000: file=%O, start=$1000, size=126; -# MEM001: file=%O, start=$0080, size=25; +# MEM001: file=%O, start=$0080, size=111; } SEGMENTS { CODE: load=MAIN, type=rw; diff --git a/SourceGen/SGTestData/Expected/20152-local-variables_merlin32.S b/SourceGen/SGTestData/Expected/20152-local-variables_merlin32.S index ba48085..886ecd3 100644 --- a/SourceGen/SGTestData/Expected/20152-local-variables_merlin32.S +++ b/SourceGen/SGTestData/Expected/20152-local-variables_merlin32.S @@ -109,5 +109,60 @@ DPCODE nop :SPLIT2 lda $2c ldx $5678 beq :SPLIT2 + nop + clc + xce + rep #$30 + mx %00 + pea ^STRING + pea STRING + jsl STRLEN + sec + xce + mx %11 + jmp L00E6 + +STRING asc 'testing' + dfb $00 + +]LEN equ $f2 +]PTR equ $f4 +]ARG equ $fd + mx %00 +STRLEN phd + tsc + sec + sbc #$00f7 + tcd + adc #$00f0 + tcs + stz ]LEN +:L00C1 ldx ]ARG+2 + lda ]ARG + inc ]ARG + bne :L00CB + inc ]ARG+2 +:L00CB sta ]PTR + stx ]PTR+2 + lda []PTR] + and #$00ff + beq :L00DA + inc ]LEN + bra :L00C1 + +:L00DA lda ]LEN + tay + tdc + clc + adc #$00f7 + tcs + tya + pld + rtl + + mx %11 +L00E6 bit ]ARG+2 + bit: $00ff + bit $0100 rts diff --git a/SourceGen/SGTestData/Source/20152-local-variables.S b/SourceGen/SGTestData/Source/20152-local-variables.S index bd1a5ea..151078f 100644 --- a/SourceGen/SGTestData/Source/20152-local-variables.S +++ b/SourceGen/SGTestData/Source/20152-local-variables.S @@ -155,4 +155,92 @@ LOCAL1 lda #$2c ;EDIT: format as ASCII LOCAL2 lda $2c ;EDIT: format as ASCII ldx $5678 ;put empty variable table here beq LOCAL2 + +; Test C-style call frame (issue #96). + nop + clc + xce + rep #$30 + pea ^STRING + pea STRING + jsl STRLEN + sec + xce + + jmp AFTER_STRLEN + +STRING asc 'testing',00 + +; C sample, for something like: + +; int strlen(const char* arg) { +; len = 0; +; while (*arg++ != '\0') +; len++; +; return len; +; } +; +; Assume SP at $2000 before call. On entry: +; $2000 string-$00 +; $1fff string-bank +; $1ffe string-hi +; $1ffd string-lo +; $1ffc ret-bank +; $1ffb ret-hi +; $1ffa ret-lo +; S=$1ff9 +; +; After call frame set up: +; $1ff9 saved-D-hi +; $1ff8 saved-D-lo +; S=$1ff7 before SBC/ADC +; $1ff7 (ptr-$00) +; $1ff6 (ptr-bank) +; $1ff5 (ptr-hi) +; $1ff4 (ptr-lo) +; $1ff3 (len-hi) +; $1ff2 (len-lo) +; +; D=$1f00 +; S=$1ff1 +; +]LEN equ $f2 ;2 bytes +]PTR equ $f4 ;4 bytes +]ARG equ $fd ;4 bytes; spans [$fd,$100] + + mx %00 +STRLEN phd + tsc + sec + sbc #$00f7 + tcd + adc #$00f0 ;note carry set + tcs + stz ]LEN +:Loop ldx ]ARG+2 + lda ]ARG + inc ]ARG + bne :NoInc + inc ]ARG+2 +:NoInc sta ]PTR + stx ]PTR+2 + lda []PTR] + and #$00ff + beq :Ret + inc ]LEN + bra :Loop +:Ret lda ]LEN + tay + tdc + clc + adc #$00f7 + tcs + tya + pld + rtl + +AFTER_STRLEN + bit $ff + bit: $00ff + bit $0100 rts