OpenCores
URL https://opencores.org/ocsvn/copyblaze/copyblaze/trunk

Subversion Repositories copyblaze

[/] [copyblaze/] [trunk/] [copyblaze/] [sw/] [tools/] [asm/] [pBlazASM/] [pBlazASM/] [pbParser.c] - Blame information for rev 46

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ameziti
/*
2
 *  Copyright © 2003..2010 : Henk van Kampen <henk@mediatronix.com>
3
 *
4
 *      This file is part of pBlazASM.
5
 *
6
 *  pBlazASM is free software: you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation, either version 3 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  pBlazASM is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with pBlazASM.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
 
20
#include <stdlib.h>
21
#include <stdio.h>
22
#include <ctype.h>
23
#include <stdint.h>
24
#include <string.h>
25
 
26
#include "pbTypes.h"
27
#include "pbSymbols.h"
28
#include "pbLexer.h"
29
#include "pbErrors.h"
30
 
31
//#ifdef _MSC_VER       //Microsoft Visual C doesn't have strcasemcp, but has stricmp instead
32
#define strcasecmp      stricmp
33
//#endif
34
 
35
 
36
/**
37
 * pBlazASM work horse
38
 * @file pBParser.c
39
 */
40
 
41
/**
42
 * assemler states
43
 */
44
typedef enum {
45
        bsINIT, bsLABEL, bsLABELED, bsSYMBOL, bsOPCODE, bsDIRECTIVE, bsOPERAND, bsEND
46
} build_state ;
47
 
48
static bool bMode = false ; //! KCPSM mode, accepts 'NAMEREG' etc
49
static bool bCode = true ; // list code
50
static uint32_t gCode[ 1024 + 256 / 2 ] ; // code space and scratchpad space (in words)
51
static char * gSource ; // source filename for error printer
52
static int gLinenr = 0 ; // current line number
53
static uint32_t gPC = 0 ; // current code counter
54
static uint32_t gSCR = 2048 ; // current scratchpad counter
55
 
56
/**
57
 * error strings
58
 */
59
static const char * s_errors[] =
60
        {
61
                "<none>", "unexpected tokens", "doubly defined", "undefined", "phasing error", "missing symbol",
62
                "syntax error", "syntax error in expression", "syntax error in operand", "syntax error in value", "value out of range",
63
                "syntax error in operator", "syntax error, register expected", "comma expected", "unexpected characters",
64
                "expression expected", "code size > 1024", "<not-implemented>", "<internal error>" } ;
65
 
66
static error_t expression( uint32_t * result ) ;
67
 
68
/**
69
 * processOperator
70
 * handle 'expression' <operator> 'term'
71
 * @param result value to operate on
72
 * @param term value to operate with
73
 * @param oper ref to operator to be used
74
 * @return success
75
 */
76
static bool processOperator( unsigned int * result, unsigned int term, symbol_t ** oper ) {
77
        if ( *oper == NULL ) {
78
                *result = term ;
79
                return true ;
80
        }
81
        switch ( ( *oper )->subtype ) {
82
        case stMUL :
83
                *result *= term ;
84
                break ;
85
        case stDIV :
86
                *result /= term ;
87
                break ;
88
        case stMOD :
89
                *result %= term ;
90
                break ;
91
        case stADD :
92
                *result += term ;
93
                break ;
94
        case stSUB :
95
                *result -= term ;
96
                break ;
97
        case stIOR :
98
                *result |= term ;
99
                break ;
100
        case stXOR :
101
                *result ^= term ;
102
                break ;
103
        case stAND :
104
                *result &= term ;
105
                break ;
106
        case stSHL :
107
                *result <<= term ;
108
                break ;
109
        case stSHR :
110
                *result >>= term ;
111
                break ;
112
        default :
113
                return false ;
114
        }
115
        *oper = NULL ;
116
        return true ;
117
}
118
 
119
/**
120
 * convert escaped char's
121
 * @param p ref to character sequence
122
 * @return converted character
123
 */
124
static char convert_char( char * * p ) {
125
        int r = 0 ;
126
        char * s = *p ;
127
 
128
        if ( *s == '\\' ) { // '\r' or '\013'
129
                s++ ;
130
                switch ( *s++ ) { // \a \b \f \n \r \t \v
131
                case '\'' :
132
                        r = '\'' ;
133
                        break ;
134
                case '\\' :
135
                        r = '\\' ;
136
                        break ;
137
                case '"' :
138
                        r = '"' ;
139
                        break ;
140
                case 'a' :
141
                case 'A' :
142
                        r = '\a' ;
143
                        break ;
144
                case 'b' :
145
                case 'B' :
146
                        r = '\b' ;
147
                        break ;
148
                case 'f' :
149
                case 'F' :
150
                        r = '\f' ;
151
                        break ;
152
                case 'n' :
153
                case 'N' :
154
                        r = '\n' ;
155
                        break ;
156
                case 'r' :
157
                case 'R' :
158
                        r = '\r' ;
159
                        break ;
160
                case 't' :
161
                case 'T' :
162
                        r = '\t' ;
163
                        break ;
164
                case 'v' :
165
                case 'V' :
166
                        r = '\v' ;
167
                        break ;
168
 
169
                case 'x' :
170
                case 'X' :
171
                        if ( sscanf( s, "%x", &r ) != 1 )
172
                                return etLEX ;
173
                        while ( isxdigit( *s ) )
174
                                s++ ;
175
                        break ;
176
                case '0' :
177
                        --s ;
178
                        if ( sscanf( s, "%o", &r ) != 1 )
179
                                return etLEX ;
180
                        while ( isdigit( *s ) && *s != '8' && *s != '9' )
181
                                s++ ;
182
                        break ;
183
                default :
184
                        return etLEX ;
185
                }
186
        } else
187
                r = *s++ ;
188
        *p = s ;
189
        return r ;
190
}
191
 
192
/**
193
 * convert escaped char's in a string
194
 * @param s string to be converted
195
 * @return new string with result (needs to be freeed)
196
 */
197
static char * convert_string( char * s ) {
198
        char * r = calloc( 1, 256 ), *p ;
199
 
200
        for ( p = r ; *s != '\0' ; )
201
                *p++ = convert_char( &s ) ;
202
        *p++ = '\0' ;
203
        return r ;
204
}
205
 
206
/**
207
 * term processing
208
 * @param resulting value of term
209
 * @result error code
210
 */
211
static error_t term( uint32_t * result ) {
212
        symbol_t * oper = NULL ;
213
        const char * p = NULL ;
214
        symbol_t * h = NULL ;
215
        error_t e = etNONE ;
216
        char * s = NULL ;
217
        uint32_t val ;
218
 
219
        // full expression handling
220
        if ( tok_current()->type == tNONE )
221
                return etEXPR ;
222
 
223
        if ( tok_current()->type == tOPERATOR )
224
                oper = tok_next() ;
225
 
226
        s = tok_current()->text ;
227
        switch ( tok_current()->type ) {
228
        case tDEC :
229
                if ( sscanf( s, "%d", &val ) != 1 )
230
                        return etEXPR ;
231
                break ;
232
        case tCHAR :
233
                val = convert_char( &s ) ;
234
                break ;
235
        case tHEX :
236
                if ( sscanf( s, "%X", &val ) != 1 )
237
                        return etEXPR ;
238
                break ;
239
        case tBIN :
240
                // parse a binary value
241
                val = 0 ;
242
                for ( p = s ; *p != 0 ; p++ ) {
243
                        val <<= 1 ;
244
                        if ( *p == '1' )
245
                                val |= 1 ;
246
                }
247
                break ;
248
        case tIDENT :
249
                h = find_symbol( s, false ) ;
250
                if ( h == NULL )
251
                        return etUNDEF ;
252
                val = h->value ;
253
                if ( h->type != tVALUE && h->type != tLABEL )
254
                        return etVALUE ;
255
                break ;
256
        case tLPAREN :
257
                tok_next() ;
258
                e = expression( &val ) ;
259
                if ( e != etNONE )
260
                        return e ;
261
                if ( tok_current()->type != tRPAREN )
262
                        return etEXPR ;
263
                break ;
264
        default :
265
                return etEXPR ;
266
        }
267
        tok_next() ;
268
        if ( oper != NULL ) {
269
                switch ( oper->subtype ) {
270
                case stSUB :
271
                        *result = -val ;
272
                        break ;
273
                case stTILDA :
274
                        *result = ~val ;
275
                        break ;
276
                default :
277
                        return etOPERATOR ;
278
                }
279
        } else
280
                *result = val ;
281
        return etNONE ;
282
}
283
 
284
/**
285
 * expression processing
286
 * depending of current bMode
287
 * @param result resulting value of expression
288
 * @return error code
289
 */
290
static error_t expression( uint32_t * result ) {
291
        symbol_t * h = NULL ;
292
        char * s = NULL ;
293
        symbol_t * oper = NULL ;
294
        error_t e = etNONE ;
295
        uint32_t val ;
296
 
297
        *result = 0 ;
298
 
299
        // crippled expression handling
300
        while ( bMode && tok_current()->type != tNONE ) {
301
                switch ( tok_current()->type ) {
302
                case tLPAREN :
303
                        tok_next() ;
304
                        e = expression( &val ) ;
305
                        if ( e != etNONE )
306
                                return e ;
307
                        if ( !processOperator( result, val, &oper ) )
308
                                return etOPERATOR ;
309
                case tRPAREN :
310
                        tok_next() ;
311
                        return etNONE ;
312
                case tCOMMA :
313
                        return etNONE ;
314
                case tIDENT :
315
                        s = tok_current()->text ;
316
                        h = find_symbol( s, false ) ;
317
                        if ( h != NULL ) {
318
                                val = h->value ;
319
                        } else if ( sscanf( s, "%X", &val ) != 1 )
320
                                return etEXPR ;
321
                        tok_next() ;
322
                        *result = val ;
323
                        return etNONE ;
324
                default :
325
                        return etEXPR ;
326
                }
327
        }
328
 
329
        if ( tok_current()->type == tNONE ) {
330
                return etEMPTY ;
331
        }
332
 
333
        // full expression handling
334
        while ( tok_current()->type != tNONE ) {
335
                switch ( tok_current()->type ) {
336
                case tLPAREN :
337
                        tok_next() ;
338
                        e = expression( &val ) ;
339
                        if ( e != etNONE )
340
                                return e ;
341
                        if ( tok_current()->type == tRPAREN ) {
342
                                tok_next() ;
343
                        } else
344
                                return etEXPR ;
345
                        break ;
346
                case tOPERATOR :
347
                case tDEC :
348
                case tCHAR :
349
                case tHEX :
350
                case tBIN :
351
                case tIDENT :
352
                        e = term( &val ) ;
353
                        if ( e != etNONE )
354
                                return e ;
355
                        break ;
356
                default :
357
                        return etNONE ;
358
                }
359
                if ( oper != NULL ) {
360
                        if ( !processOperator( result, val, &oper ) )
361
                                return etOPERATOR ;
362
                        oper = NULL ;
363
                } else
364
                        *result = val ;
365
                if ( tok_current()->type == tOPERATOR )
366
                        oper = tok_next() ;
367
                else
368
                        break ;
369
        }
370
        return etNONE ;
371
}
372
 
373
/**
374
 * destreg: process destination register
375
 * @param result value of destination register, shifted already in position
376
 * @return success
377
 */
378
static bool destreg( uint32_t * result ) {
379
        symbol_t * h ;
380
 
381
        if ( result == NULL )
382
                return false ;
383
        *result = 0 ;
384
 
385
        h = find_symbol( tok_current()->text, false ) ;
386
        if ( h != NULL && h->type == tREGISTER ) {
387
                tok_next() ;
388
                *result = h->value << 8 ;
389
                return true ;
390
        }
391
        return false ;
392
}
393
 
394
/**
395
 * srcreg: process source register, accepts parens
396
 * @param result value of source register, shifted already in position
397
 * @return success
398
 */
399
static bool srcreg( uint32_t * result ) {
400
        symbol_t * h ;
401
        bool bpar = false ;
402
        bool retval = true ;
403
        symbol_t * back = tok_current() ;
404
 
405
        if ( result == NULL )
406
                return false ;
407
        *result = 0 ;
408
 
409
        if ( tok_current()->type == tLPAREN ) {
410
                bpar = true ;
411
                tok_next() ;
412
        }
413
 
414
        h = find_symbol( tok_current()->text, false ) ;
415
        if ( h == NULL || h->type != tREGISTER ) {
416
                retval = false ;
417
                goto finally ;
418
        }
419
        *result = h->value << 4 ;
420
 
421
        tok_next() ;
422
        if ( bpar ) {
423
                if ( tok_current()->type == tRPAREN )
424
                        tok_next() ;
425
                else {
426
                        retval = false ;
427
                        goto finally ;
428
                }
429
        }
430
 
431
        finally: {
432
                if ( !retval )
433
                        tok_back( back ) ;
434
                return retval ;
435
        }
436
}
437
 
438
/**
439
 * eat comma in token stream
440
 * @return success
441
 */
442
static bool comma( void ) {
443
        if ( tok_current()->type == tCOMMA ) {
444
                tok_next() ;
445
                return true ;
446
        } else
447
                return false ;
448
}
449
 
450
/**
451
 * process condition token
452
 * @param result value of condition, already in position
453
 * @return success
454
 */
455
static bool condition( uint32_t * result ) {
456
        symbol_t * h ;
457
 
458
        if ( result == NULL )
459
                return false ;
460
        *result = 0 ;
461
 
462
        if ( tok_current()->type != tNONE ) {
463
                h = find_symbol( tok_current()->text, true ) ;
464
                if ( h != NULL && h->type == tCONDITION ) {
465
                        tok_next() ;
466
                        *result = h->value ;
467
                        return true ;
468
                }
469
        }
470
        return false ;
471
}
472
 
473
/**
474
 * process enable token
475
 * @param result value of enable, already in position
476
 * @return success
477
 */
478
static bool enadis( uint32_t * result ) {
479
        symbol_t * h ;
480
 
481
        if ( result == NULL )
482
                return false ;
483
        *result = 0 ;
484
 
485
        h = find_symbol( tok_current()->text, true ) ;
486
        if ( h != NULL && h->type == tOPCODE && h->subtype == stINTI ) {
487
                tok_next() ;
488
                *result = h->value & 1 ;
489
                return true ;
490
        }
491
        return false ;
492
}
493
 
494
/**
495
 * process indexed token
496
 * @param result value of indexed construct, already in position
497
 * @return success
498
 */
499
static bool indexed( uint32_t * result ) {
500
        symbol_t * h ;
501
 
502
        if ( result == NULL )
503
                return false ;
504
        *result = 0 ;
505
 
506
        if ( tok_current()->type != tNONE ) {
507
                h = find_symbol( tok_current()->text, true ) ;
508
                if ( h != NULL && h->type == tINDEX ) {
509
                        tok_next() ;
510
                        *result = h->value ;
511
                        return true ;
512
                }
513
        }
514
        return false ;
515
}
516
 
517
 
518
/**
519
 * first pass of assembler
520
 * process all source lines and build symbol table
521
 * @return error code
522
 */
523
static error_t build( void ) {
524
        build_state state = bsINIT ;
525
        symbol_t * symtok = NULL ;
526
        symbol_t * h = NULL ;
527
        symbol_t * r = NULL ;
528
        uint32_t result = 0 ;
529
        error_t e = etNONE ;
530
 
531
        // process statement
532
        for ( tok_first(), state = bsINIT ; state != bsEND ; tok_next() ) {
533
                switch ( tok_current()->type ) {
534
                case tNONE :
535
                        // empty line?
536
                        if ( state != bsINIT && state != bsLABELED )
537
                                return etSYNTAX ;
538
                        state = bsEND ;
539
                        break ;
540
 
541
                // opcode or symbol definition
542
                case tIDENT :
543
                        // opcode or directive?
544
                        h = find_symbol( tok_current()->text, false ) ;
545
                        if ( h == NULL ) {
546
                                h = find_symbol( tok_current()->text, true ) ;
547
                                if ( h == NULL || h->type != tOPCODE )
548
                                        h = NULL ;
549
                        }
550
                        if ( h != NULL ) {
551
                                switch ( h->type ) {
552
                                case tLABEL :
553
                                        if ( state != bsINIT )
554
                                                return etSYNTAX ;
555
                                        if ( h->subtype != stDOT )
556
                                                return etSYNTAX ;
557
                                        h->value = gPC ;
558
                                        symtok = tok_current() ;
559
                                        state = bsLABEL ;
560
                                        break ;
561
 
562
                                case tOPCODE :
563
                                        if ( state != bsINIT && state != bsLABELED )
564
                                                return etSYNTAX ;
565
                                        gPC += 1 ;
566
                                        state = bsEND ; // we know enough for now
567
                                        break ;
568
 
569
                                case tDIRECTIVE :
570
                                        switch ( h->subtype ) {
571
 
572
                                        case stPAGE :
573
                                                state = bsEND ;
574
                                                break ;
575
 
576
                                        // ORG
577
                                        case stADDRESS :
578
                                        case stORG :
579
                                                if ( state != bsINIT )
580
                                                        return etSYNTAX ;
581
                                                tok_next() ;
582
                                                if ( ( e = expression( &result ) ) == etNONE ) {
583
                                                        if ( result >= 1024 ) // within code range
584
                                                                return etRANGE ;
585
                                                        gPC = result ;
586
                                                } else
587
                                                        return e ;
588
                                                state = bsEND ;
589
                                                break ;
590
 
591
                                                // _SRC
592
                                        case stSCRATCHPAD :
593
                                                if ( state != bsINIT )
594
                                                        return etSYNTAX ;
595
                                                tok_next() ;
596
                                                if ( ( e = expression( &result ) ) == etNONE ) {
597
                                                        if ( result >= 1024 + 128 ) // within code + scratchpad range
598
                                                                return etRANGE ;
599
                                                        gSCR = result * 2 ;
600
                                                } else
601
                                                        return e ;
602
                                                state = bsEND ;
603
                                                break ;
604
 
605
                                                // EQU
606
                                        case stEQU :
607
                                                if ( state != bsSYMBOL )
608
                                                        return etSYNTAX ;
609
                                                tok_next() ;
610
                                                if ( symtok != NULL ) {
611
                                                        // register clone?
612
                                                        r = find_symbol( tok_current()->text, false ) ;
613
                                                        if ( r != NULL && r->type == tREGISTER ) {
614
                                                                if ( !add_symbol( tREGISTER, stCLONE, symtok->text, r->value ) )
615
                                                                        return etDOUBLE ;
616
                                                                else {
617
                                                                        state = bsEND ;
618
                                                                        break ;
619
                                                                }
620
                                                        } else if ( ( e = expression( &result ) ) == etNONE ) {
621
                                                                // normal expression?
622
                                                                if ( !add_symbol( tVALUE, stINT, symtok->text, result ) )
623
                                                                        return etDOUBLE ;
624
                                                        } else
625
                                                                return e ;
626
                                                } else
627
                                                        return etMISSING ;
628
                                                state = bsEND ;
629
                                                break ;
630
 
631
                                        case stCONSTANT :
632
                                                if ( state != bsINIT )
633
                                                        return etSYNTAX ;
634
                                                tok_next() ;
635
                                                symtok = tok_next() ;
636
                                                if ( symtok->type != tIDENT )
637
                                                        return etSYNTAX ;
638
                                                if ( !comma() )
639
                                                        return etCOMMA ;
640
                                                // normal expression?
641
                                                if ( ( e = expression( &result ) ) == etNONE ) {
642
                                                        if ( !add_symbol( tVALUE, stINT, symtok->text, result ) )
643
                                                                return etDOUBLE ;
644
                                                } else
645
                                                        return e ;
646
                                                state = bsEND ;
647
                                                break ;
648
 
649
                                        case stNAMEREG :
650
                                                if ( state != bsINIT )
651
                                                        return etSYNTAX ;
652
                                                tok_next() ;
653
                                                symtok = tok_next() ;
654
                                                if ( symtok->type != tIDENT )
655
                                                        return etSYNTAX ;
656
                                                r = find_symbol( symtok->text, true ) ;
657
                                                if ( r == NULL || r->type != tREGISTER )
658
                                                        return etREGISTER ;
659
                                                if ( !comma() )
660
                                                        return etCOMMA ;
661
                                                if ( tok_current()->type == tIDENT ) {
662
                                                        if ( !add_symbol( tREGISTER, stCLONE, tok_current()->text, r->value ) )
663
                                                                return etDOUBLE ;
664
                                                } else
665
                                                        return etSYNTAX ;
666
                                                state = bsEND ;
667
                                                break ;
668
 
669
                                        case stSFR :
670
                                                // DS, pBlazIDE support
671
                                        case stDS :
672
                                        case stDSIN :
673
                                        case stDSOUT :
674
                                        case stDSIO :
675
                                        case stDSRAM :
676
                                        case stDSROM :
677
                                                if ( state != bsSYMBOL )
678
                                                        return etSYNTAX ;
679
                                                tok_next() ;
680
                                                if ( symtok != NULL ) {
681
                                                        if ( ( e = expression( &result ) ) == etNONE ) {
682
                                                                if ( !add_symbol( tVALUE, stINT, symtok->text, result ) )
683
                                                                        return etDOUBLE ;
684
                                                        } else
685
                                                                return e ;
686
                                                } else
687
                                                        return etMISSING ;
688
                                                state = bsEND ;
689
                                                break ;
690
 
691
                                                // .BYT etc
692
                                        case stBYTE :
693
                                        case stWORD_BE : case stWORD_LE :
694
                                        case stLONG_BE : case stLONG_LE :
695
                                                if ( state != bsINIT && state != bsSYMBOL )
696
                                                        return etSYNTAX ;
697
                                                tok_next() ;
698
                                                if ( symtok && !add_symbol( tVALUE, stINT, symtok->text, ( gSCR ) & 0xFF ) )
699
                                                        return etDOUBLE ;
700
                                                do {
701
                                                        if ( ( e = expression( &result ) ) != etNONE ) {
702
                                                                if ( e == etEMPTY )
703
                                                                        break ; // allow an empty expression list for generating a symbol only
704
                                                                else
705
                                                                        return e ;
706
                                                        }
707
                                                        switch ( h->subtype ) {
708
                                                        case stLONG_BE :
709
                                                        case stLONG_LE :
710
                                                                gSCR += 2 ;
711
                                                        case stWORD_BE :
712
                                                        case stWORD_LE :
713
                                                                gSCR += 1 ;
714
                                                        default :
715
                                                                gSCR += 1 ;
716
                                                        }
717
                                                } while ( comma() ) ;
718
                                                state = bsEND ;
719
                                                break ;
720
 
721
                                                // .BUF
722
                                        case stBUFFER :
723
                                                if ( state != bsINIT && state != bsSYMBOL )
724
                                                        return etSYNTAX ;
725
                                                tok_next() ;
726
                                                if ( symtok && !add_symbol( tVALUE, stINT, symtok->text, ( gSCR ) & 0xFF ) )
727
                                                        return etDOUBLE ;
728
                                                if ( ( e = expression( &result ) ) == etNONE ) {
729
                                                        if ( result < 256 )
730
                                                                gSCR += result ;
731
                                                        else
732
                                                                return etRANGE ;
733
                                                } else
734
                                                        return e ;
735
                                                state = bsEND ;
736
                                                break ;
737
 
738
                                                // .TXT
739
                                        case stTEXT :
740
                                                if ( state != bsINIT && state != bsSYMBOL )
741
                                                        return etSYNTAX ;
742
                                                tok_next() ;
743
                                                if ( symtok && !add_symbol( tVALUE, stINT, symtok->text, ( gSCR ) & 0xFF ) )
744
                                                        return etDOUBLE ;
745
                                                if ( tok_current()->type == tSTRING ) {
746
                                                        char * dup = convert_string( tok_current()->text ) ;
747
                                                        gSCR += strlen( dup ) + 1 ;
748
                                                        free( dup ) ;
749
                                                } else
750
                                                        return etEXPR ;
751
                                                state = bsEND ;
752
                                                break ;
753
 
754
                                        case stVHDL :
755
                                        case stHEX :
756
                                        case stMEM :
757
                                        case stCOE :
758
                                                if ( state != bsINIT )
759
                                                        return etSYNTAX ;
760
                                                state = bsEND ;
761
                                                break ;
762
 
763
                                        default :
764
                                                return etSYNTAX ;
765
                                        }
766
                                        break ;
767
                                default :
768
                                        return etDOUBLE ;
769
                                }
770
                        } else if ( state == bsINIT ) {
771
                                // not known yet, label or symbol definition?
772
                                symtok = tok_current() ;
773
                                state = bsSYMBOL ;
774
                        } else {
775
                                h = find_symbol( tok_current()->text, true ) ;
776
                                // opcode mnemonic in lower/mixed case?
777
                                if ( h != NULL && h->type == tOPCODE ) {
778
                                        if ( state != bsINIT && state != bsLABELED )
779
                                                return etSYNTAX ;
780
                                        gPC += 1 ;
781
                                        state = bsEND ; // we know enough for now
782
                                }
783
                        }
784
                        break ;
785
 
786
                case tCOLON :
787
                        if ( state == bsLABEL )
788
                                ;
789
                        else if ( state != bsSYMBOL )
790
                                return etSYNTAX ;
791
                        else if ( !add_symbol( tLABEL, symtok->subtype, symtok->text, gPC ) )
792
                                return etDOUBLE ;
793
                        state = bsLABELED ;
794
                        break ;
795
 
796
                default :
797
                        return etSYNTAX ;
798
                }
799
        }
800
        return etNONE ;
801
}
802
 
803
/**
804
 * second pass of assembler
805
 * process all source lines and build code and scratchpad contents
806
 * @param addr ref to address value for listing
807
 * @param code ref to code value for listing
808
 * @return error code
809
 */
810
static error_t assemble( uint32_t * addr, uint32_t * code ) {
811
        build_state state = bsINIT ;
812
        symbol_t * h = NULL ;
813
        uint32_t result = 0 ;
814
        uint32_t operand1 = 0 ;
815
        uint32_t operand2 = 0 ;
816
        uint32_t opcode = 0 ;
817
        uint32_t oPC = 0 ;
818
        error_t e = etNONE ;
819
 
820
        *addr = 0xFFFFFFFF ;
821
        *code = 0xFFFFFFFF ;
822
 
823
        // process statement
824
        for ( tok_first(), state = bsINIT ; state != bsEND ; ) {
825
                switch ( tok_current()->type ) {
826
                case tNONE :
827
                        // empty line?
828
                        if ( state != bsINIT && state != bsLABELED )
829
                                return etSYNTAX ;
830
                        state = bsEND ;
831
                        break ;
832
 
833
                case tIDENT :
834
                        h = find_symbol( tok_current()->text, false ) ;
835
                        // opcode mnemonic in lower/mixed case?
836
                        if ( h == NULL ) {
837
                                h = find_symbol( tok_current()->text, true ) ;
838
                                if ( h == NULL || h->type != tOPCODE )
839
                                        h = NULL ;
840
                        }
841
                        if ( h != NULL ) {
842
                                switch ( h->type ) {
843
                                // opcodes
844
                                case tOPCODE :
845
                                        if ( state != bsINIT && state != bsLABELED )
846
                                                return etSYNTAX ;
847
                                        tok_next() ;
848
                                        opcode = 0xFFFFFFFF ;
849
                                        operand1 = 0 ;
850
                                        operand2 = 0 ;
851
                                        oPC = gPC ;
852
                                        gPC += 1 ;
853
 
854
                                        switch ( h->subtype ) {
855
                                        case stMOVE :
856
                                                if ( !destreg( &operand1 ) )
857
                                                        return etREGISTER ;
858
                                                if ( !comma() )
859
                                                        return etCOMMA ;
860
                                                if ( !srcreg( &operand2 ) ) {
861
                                                        if ( ( e = expression( &operand2 ) ) != etNONE )
862
                                                                return e ;
863
                                                        opcode = h->value | operand1 | ( operand2 & 0xFF ) ;
864
                                                } else
865
                                                        opcode = h->value | operand1 | ( operand2 & 0xFF ) | 0x01000 ;
866
                                                break ;
867
 
868
                                        case stCJMP :
869
                                                if ( condition( &operand1 ) ) {
870
                                                        if ( !comma() )
871
                                                                return etCOMMA ;
872
                                                }
873
                                                if ( ( e = expression( &operand2 ) ) != etNONE )
874
                                                        return e ;
875
                                                opcode = h->value | operand1 | ( operand2 & 0x3FF ) ;
876
                                                break ;
877
 
878
                                        case stCSKP :
879
                                                condition( &operand1 ) ;
880
                                                opcode = h->value | operand1 | ( oPC + 2 ) ;
881
                                                break ;
882
 
883
                                        case stCRET :
884
                                                condition( &operand1 ) ;
885
                                                opcode = h->value | operand1 ;
886
                                                break ;
887
 
888
                                        case stINT :
889
                                                opcode = h->value ;
890
                                                break ;
891
 
892
                                        case stINTI :
893
                                                if ( !bMode )
894
                                                        return etNOTIMPL ;
895
                                                opcode = h->value ;
896
                                                if ( tok_current()->type != tIDENT || strcasecmp( tok_current()->text, "INTERRUPT" ) != 0 )
897
                                                        return etMISSING ;
898
                                                tok_next() ;
899
                                                break ;
900
 
901
                                        case stINTE :
902
                                                opcode = h->value ;
903
                                                if ( enadis( &operand1 ) )
904
                                                        opcode = ( h->value & 0xFFFFE ) | operand1 ;
905
                                                break ;
906
 
907
                                        case stIO :
908
                                                if ( !destreg( &operand1 ) )
909
                                                        return etREGISTER ;
910
                                                if ( !comma() )
911
                                                        return etCOMMA ;
912
                                                if ( !srcreg( &operand2 ) ) {
913
                                                        if ( !indexed( &operand2 ) ) {
914
                                                                if ( ( e = expression( &operand2 ) ) != etNONE )
915
                                                                        return e ;
916
                                                                opcode = h->value | operand1 | ( operand2 & 0xFF ) ;
917
                                                        } else
918
                                                                opcode = h->value | operand1 | operand2 ;
919
                                                } else
920
                                                        opcode = h->value | operand1 | ( operand2 & 0xFF ) | 0x01000 ;
921
                                                break ;
922
 
923
                                        case stSHIFT :
924
                                                if ( !destreg( &operand1 ) )
925
                                                        return etREGISTER ;
926
                                                opcode = h->value | operand1 ;
927
                                                break ;
928
 
929
                                        case stINST :
930
                                                if ( ( e = expression( &opcode ) ) != etNONE )
931
                                                        return e ;
932
                                                break ;
933
 
934
                                        default :
935
                                                return etNOTIMPL ;
936
                                        }
937
                                        if ( opcode == 0xFFFFFFFF )
938
                                                return etINTERNAL ;
939
                                        if ( oPC < 1024 ) {
940
                                                gCode[ oPC ] = opcode ;
941
                                                *addr = oPC ;
942
                                                *code = opcode ;
943
                                        } else
944
                                                return etRANGE ;
945
                                        state = bsEND ;
946
                                        break ;
947
 
948
                                        // directives
949
                                case tDIRECTIVE :
950
                                        tok_next() ;
951
                                        switch ( h->subtype ) {
952
 
953
                                        case stPAGE :
954
                                                break ;
955
 
956
                                        case stADDRESS :
957
                                                if ( !bMode )
958
                                                        return etNOTIMPL ;
959
                                        case stORG :
960
                                                if ( state != bsINIT )
961
                                                        return etSYNTAX ;
962
                                                if ( ( e = expression( &result ) ) == etNONE ) {
963
                                                        if ( result >= 1024 )
964
                                                                return etRANGE ;
965
                                                        gPC = result ;
966
                                                        *addr = gPC ;
967
                                                } else
968
                                                        return e ;
969
                                                break ;
970
 
971
                                        case stSCRATCHPAD :
972
                                                if ( state != bsINIT )
973
                                                        return etSYNTAX ;
974
                                                if ( ( e = expression( &result ) ) == etNONE ) {
975
                                                        // within code range
976
                                                        if ( result >= 1024 + 256 / 2 )
977
                                                                return etRANGE ;
978
                                                        gSCR = result * 2 ;
979
                                                        *addr = gSCR ;
980
                                                } else
981
                                                        return e ;
982
                                                break ;
983
 
984
                                        case stEQU :
985
                                                if ( state != bsSYMBOL )
986
                                                        return etSYNTAX ;
987
                                                // NO-OP, just eat tokens in an orderly way
988
                                                if ( destreg( &result ) ) {
989
                                                } else if ( ( e = expression( &result ) ) == etNONE ) {
990
                                                        *code = result ;
991
                                                } else
992
                                                        return e ;
993
                                                break ;
994
 
995
                                        case stSFR :
996
                                        case stDS :
997
                                        case stDSIN :
998
                                        case stDSOUT :
999
                                        case stDSIO :
1000
                                        case stDSRAM :
1001
                                        case stDSROM :
1002
                                                if ( state != bsSYMBOL )
1003
                                                        return etSYNTAX ;
1004
                                                // NO-OP, just eat tokens in an orderly way
1005
                                                do {
1006
                                                        if ( ( e = expression( &result ) ) == etNONE ) {
1007
                                                        } else
1008
                                                                return e ;
1009
                                                } while ( comma() ) ;
1010
                                                break ;
1011
 
1012
                                        case stBYTE :
1013
                                                if ( state != bsINIT && state != bsSYMBOL )
1014
                                                        return etSYNTAX ;
1015
                                                *addr = gSCR ;
1016
                                                *code = 0xFFFFFFFF ;
1017
                                                do {
1018
                                                        if ( ( e = expression( &result ) ) == etNONE ) {
1019
                                                                if ( result > 0xFF )
1020
                                                                        return etOVERFLOW ;
1021
                                                                if ( ( gSCR & 1 ) == 0 )
1022
                                                                        gCode[ gSCR / 2 ] = ( gCode[ gSCR / 2 ] & 0x0FF00 ) | ( ( result >> 0 ) & 0x00FF ) ;
1023
                                                                else
1024
                                                                        gCode[ gSCR / 2 ] = ( gCode[ gSCR / 2 ] & 0x000FF ) | ( ( result << 8 ) & 0xFF00 ) ;
1025
                                                                gSCR += 1 ;
1026
                                                        } else if ( e == etEMPTY ) {
1027
                                                                // allow an empty expression list for generating a symbol only
1028
                                                                break ;
1029
                                                        } else
1030
                                                                return e ;
1031
                                                        // only show the first 2 bytes as a 'uint18'
1032
                                                        if ( ( ( gSCR - 1 ) & 0xFFFE ) == ( *addr & 0xFFFE ) )
1033
                                                                *code = gCode[ ( gSCR - 1 ) / 2 ] ;
1034
                                                } while ( comma() ) ;
1035
                                                break ;
1036
 
1037
                                        case stWORD_BE :
1038
                                        case stWORD_LE :
1039
                                                if ( state != bsINIT && state != bsSYMBOL )
1040
                                                        return etSYNTAX ;
1041
                                                *addr = gSCR ;
1042
                                                *code = 0xFFFFFFFF ;
1043
                                                do {
1044
                                                        if ( ( e = expression( &result ) ) == etNONE ) {
1045
                                                                if ( result > 0xFFFF )
1046
                                                                        return etOVERFLOW ;
1047
                                                                result &= 0xFFFF ;
1048
                                                                if ( h->subtype == stWORD_BE )
1049
                                                                        result = ( ( result & 0xFF00FF00 ) >> 8 ) | ( ( result & 0x00FF00FF ) << 8 ) ;
1050
                                                                if ( ( gSCR & 1 ) == 0 )
1051
                                                                        gCode[ gSCR / 2 ] = ( gCode[ gSCR / 2 ] & 0x0FF00 ) | ( ( result >> 0 ) & 0x00FF ) ;
1052
                                                                else
1053
                                                                        gCode[ gSCR / 2 ] = ( gCode[ gSCR / 2 ] & 0x000FF ) | ( ( result << 8 ) & 0xFF00 ) ;
1054
                                                                gSCR += 1 ;
1055
                                                                if ( ( gSCR & 1 ) == 0 )
1056
                                                                        gCode[ gSCR / 2 ] = ( gCode[ gSCR / 2 ] & 0x0FF00 ) | ( ( result >> 8 ) & 0x00FF ) ;
1057
                                                                else
1058
                                                                        gCode[ gSCR / 2 ] = ( gCode[ gSCR / 2 ] & 0x000FF ) | ( ( result >> 0 ) & 0xFF00 ) ;
1059
                                                                gSCR += 1 ;
1060
                                                        } else if ( e == etEMPTY ) {
1061
                                                                // allow an empty expression list for generating a symbol only
1062
                                                                break ;
1063
                                                        } else
1064
                                                                return e ;
1065
                                                        // only show the first 2 bytes as a 'uint18'
1066
                                                        if ( ( ( gSCR - 2 ) & 0xFFFE ) == ( *addr & 0xFFFE ) )
1067
                                                                *code = gCode[ ( gSCR - 2 ) / 2 ] ;
1068
                                                } while ( comma() ) ;
1069
                                                break ;
1070
 
1071
                                        case stLONG_BE :
1072
                                        case stLONG_LE :
1073
                                                if ( state != bsINIT && state != bsSYMBOL )
1074
                                                        return etSYNTAX ;
1075
                                                *addr = gSCR ;
1076
                                                *code = 0xFFFFFFFF ;
1077
                                                do {
1078
                                                        if ( ( e = expression( &result ) ) == etNONE ) {
1079
                                                                if ( h->subtype == stLONG_BE ) {
1080
                                                                        result = ( ( result & 0xFFFF0000 ) >> 16 ) | ( ( result & 0x0000FFFF ) << 16 ) ;
1081
                                                                        result = ( ( result & 0xFF00FF00 ) >> 8 ) | ( ( result & 0x00FF00FF ) << 8 ) ;
1082
                                                                }
1083
                                                                if ( ( gSCR & 1 ) == 0 )
1084
                                                                        gCode[ gSCR / 2 ] = ( gCode[ gSCR / 2 ] & 0x0FF00 ) | ( ( result >>  0 ) & 0x00FF ) ;
1085
                                                                else
1086
                                                                        gCode[ gSCR / 2 ] = ( gCode[ gSCR / 2 ] & 0x000FF ) | ( ( result <<  8 ) & 0xFF00 ) ;
1087
                                                                gSCR += 1 ;
1088
                                                                if ( ( gSCR & 1 ) == 0 )
1089
                                                                        gCode[ gSCR / 2 ] = ( gCode[ gSCR / 2 ] & 0x0FF00 ) | ( ( result >>  8 ) & 0x00FF ) ;
1090
                                                                else
1091
                                                                        gCode[ gSCR / 2 ] = ( gCode[ gSCR / 2 ] & 0x000FF ) | ( ( result >>  0 ) & 0xFF00 ) ;
1092
                                                                gSCR += 1 ;
1093
                                                                if ( ( gSCR & 1 ) == 0 )
1094
                                                                        gCode[ gSCR / 2 ] = ( gCode[ gSCR / 2 ] & 0x0FF00 ) | ( ( result >> 16 ) & 0x00FF ) ;
1095
                                                                else
1096
                                                                        gCode[ gSCR / 2 ] = ( gCode[ gSCR / 2 ] & 0x000FF ) | ( ( result >>  8 ) & 0xFF00 ) ;
1097
                                                                gSCR += 1 ;
1098
                                                                if ( ( gSCR & 1 ) == 0 )
1099
                                                                        gCode[ gSCR / 2 ] = ( gCode[ gSCR / 2 ] & 0x0FF00 ) | ( ( result >> 24 ) & 0x00FF ) ;
1100
                                                                else
1101
                                                                        gCode[ gSCR / 2 ] = ( gCode[ gSCR / 2 ] & 0x000FF ) | ( ( result >> 16 ) & 0xFF00 ) ;
1102
                                                                gSCR += 1 ;
1103
                                                        } else if ( e == etEMPTY ) {
1104
                                                                // allow an empty expression list for generating a symbol only
1105
                                                                break ;
1106
                                                        } else
1107
                                                                return e ;
1108
                                                        // only show the first 2 bytes as a 'uint18'
1109
                                                        if ( ( ( gSCR - 4 ) & 0xFFFE ) == ( *addr & 0xFFFE ) )
1110
                                                                *code = gCode[ ( gSCR - 4 ) / 2 ] ;
1111
                                                } while ( comma() ) ;
1112
                                                break ;
1113
 
1114
                                        case stBUFFER :
1115
                                                if ( state != bsINIT && state != bsSYMBOL )
1116
                                                        return etSYNTAX ;
1117
                                                if ( ( e = expression( &result ) ) == etNONE ) {
1118
                                                        if ( result < 256 ) {
1119
                                                                *addr = gSCR ;
1120
                                                                gSCR += result ;
1121
                                                                *code = 0xFFFF0000 | result ;
1122
                                                        } else
1123
                                                                return etRANGE ;
1124
                                                } else
1125
                                                        return e ;
1126
                                                break ;
1127
 
1128
                                                // _TXT
1129
                                        case stTEXT :
1130
                                                if ( state != bsINIT && state != bsSYMBOL )
1131
                                                        return etSYNTAX ;
1132
                                                if ( tok_current()->type == tSTRING ) {
1133
                                                        char * dup = convert_string( tok_current()->text ) ;
1134
                                                        int i = 0 ;
1135
 
1136
                                                        *addr = gSCR ;
1137
                                                        for ( i = 0 ; i < strlen( dup ) + 1 ; i += 1 ) {
1138
                                                                if ( ( gSCR & 1 ) == 0 )
1139
                                                                        gCode[ gSCR / 2 ] = ( gCode[ gSCR / 2 ] & 0x0FF00 ) | ( dup[ i ] & 0xFF ) ;
1140
                                                                else
1141
                                                                        gCode[ gSCR / 2 ] = ( gCode[ gSCR / 2 ] & 0x000FF ) | ( ( dup[ i ] & 0xFF ) << 8 ) ;
1142
                                                                // only show the first 2 bytes as a 'uint18'
1143
                                                                if ( ( gSCR & 0xFFFE ) == ( *addr & 0xFFFE ) )
1144
                                                                        *code = gCode[ gSCR / 2 ] ;
1145
                                                                gSCR += 1 ;
1146
                                                        }
1147
                                                        free( dup ) ;
1148
                                                } else
1149
                                                        return etEXPR ;
1150
                                                tok_next() ;
1151
                                                break ;
1152
 
1153
                                        case stVHDL :
1154
                                        case stHEX :
1155
                                        case stMEM :
1156
                                        case stCOE :
1157
                                                if ( state != bsINIT )
1158
                                                        return etSYNTAX ;
1159
                                                //                                              if ( bKCPSM_mode )
1160
                                                return etNOTIMPL ;
1161
                                                break ;
1162
 
1163
                                        case stCONSTANT :
1164
                                                if ( state != bsINIT )
1165
                                                        return etSYNTAX ;
1166
                                                tok_next() ;
1167
                                                if ( !comma() )
1168
                                                        return etCOMMA ;
1169
                                                // normal expression?
1170
                                                if ( ( e = expression( &result ) ) == etNONE ) {
1171
                                                        *code = result ;
1172
                                                } else
1173
                                                        return e ;
1174
                                                break ;
1175
 
1176
                                        case stNAMEREG :
1177
                                                if ( state != bsINIT )
1178
                                                        return etSYNTAX ;
1179
                                                if ( !bMode )
1180
                                                        return etNOTIMPL ;
1181
                                                tok_next() ;
1182
                                                tok_next() ;
1183
                                                tok_next() ;
1184
                                                break ;
1185
 
1186
                                        default :
1187
                                                return etSYNTAX ;
1188
                                        }
1189
                                        state = bsEND ;
1190
                                        break ;
1191
 
1192
                                        // labels
1193
                                case tLABEL :
1194
                                        if ( state != bsINIT )
1195
                                                return etSYNTAX ;
1196
                                        if ( h->value != gPC && h->subtype != stDOT )
1197
                                                return etPHASING ;
1198
                                        tok_next()->type = tLABEL ; // just for formatting
1199
                                        h->value = gPC ;
1200
                                        *addr = h->value ;
1201
                                        state = bsLABEL ;
1202
                                        break ;
1203
 
1204
                                        // equated values
1205
                                case tVALUE :
1206
                                case tREGISTER :
1207
                                        if ( state != bsINIT )
1208
                                                return etSYNTAX ;
1209
                                        tok_next()->subtype = stEQU ; // just for formatting
1210
                                        *code = h->value & 0xFFFF ;
1211
                                        state = bsSYMBOL ;
1212
                                        break ;
1213
 
1214
                                default :
1215
                                        return etSYNTAX ;
1216
                                }
1217
                        } else
1218
                                return etUNDEF ;
1219
                        break ;
1220
 
1221
                case tCOLON :
1222
                        // if we have a potential label, we need a ':'
1223
                        if ( state != bsLABEL )
1224
                                return etSYNTAX ;
1225
                        tok_next() ;
1226
                        state = bsLABELED ;
1227
                        break ;
1228
 
1229
                default :
1230
                        return etSYNTAX ;
1231
                }
1232
        }
1233
        // only comment may follow
1234
        if ( tok_current()->type != tNONE )
1235
                return etEND ;
1236
        return etNONE ;
1237
}
1238
 
1239
// error printer
1240
static bool error( const error_t e ) {
1241
        if ( e != etNONE ) {
1242
                fprintf( stdout, "%s:%d: %s\n", gSource, gLinenr, s_errors[ e ] ) ;
1243
                return false ;
1244
        } else
1245
                return true ;
1246
}
1247
 
1248
// dump code in mem file format
1249
static void dump_code( FILE * f, bool hex, bool zeros ) {
1250
        int h, l = 0 ;
1251
        bool b_addr = true ;
1252
 
1253
        if ( hex ) {
1254
                // find last used entry
1255
                for ( h = 0, l = 1024 ; h < 1024 ; h += 1 )
1256
                        if ( gCode[ h ] != 0xFFFC0000 && ! zeros )
1257
                                l = h ;
1258
                // list all
1259
                for ( h = 0 ; h <= l ; h += 1 )
1260
                        fprintf( f, "%05X\n", gCode[ h ] & 0x3FFFF ) ;
1261
        } else {
1262
                // list used code entries, prepend an origin
1263
                for ( h = 0 ; h < 1024 ; h += 1 ) {
1264
                        if ( gCode[ h ] == 0xFFFC0000 && ! zeros )
1265
                                b_addr = true ;
1266
                        else {
1267
                                if ( b_addr ) {
1268
                                        fprintf( f, "@%08X\n", h ) ;
1269
                                        b_addr = false ;
1270
                                }
1271
                                fprintf( f, "%05X\n", gCode[ h ] & 0x3FFFF ) ;
1272
                        }
1273
                }
1274
                // list used scratchpad entries, prepend an origin
1275
                b_addr = true ;
1276
                for ( h = 1024 ; h < 1024 + 256 / 2 ; h += 1 ) {
1277
                        if ( gCode[ h ] == 0xFFFC0000 )
1278
                                b_addr = true ;
1279
                        else {
1280
                                if ( b_addr ) {
1281
                                                fprintf( f, "@%08X\n", h ) ;
1282
                                        b_addr = false ;
1283
                                }
1284
                                fprintf( f, "%05X\n", gCode[ h ] & 0x3FFFF ) ;
1285
                        }
1286
                }
1287
        }
1288
}
1289
 
1290
// format list file
1291
static void print_line( FILE * f, error_t e, uint32_t addr, uint32_t code ) {
1292
        int n = 0 ;
1293
        char * s = NULL ;
1294
 
1295
        tok_first() ;
1296
 
1297
        if ( e != etNONE )
1298
                fprintf( f, "?? %s:\n", s_errors[ e ] ) ;
1299
 
1300
        if ( tok_current()->type == tDIRECTIVE && tok_current()->subtype == stPAGE ) {
1301
                fprintf( f, "\f" ) ;
1302
                return ;
1303
        }
1304
 
1305
        if ( bCode ) {
1306
                // code info
1307
                if ( code != 0xFFFFFFFF ) {
1308
                        if ( addr != 0xFFFFFFFF ) {
1309
                        // address info
1310
                                n += fprintf( f, "%03X ", addr ) ;
1311
                                if ( code <= 0xFFFFF )
1312
                                        n += fprintf( f, "%05X ", code ) ;
1313
                                else
1314
                                        n += fprintf( f, "  %02X  ", code & 0xFF ) ;
1315
                        } else if ( code > 0xFFFF )
1316
                                n += fprintf( f, "%08X  ", code ) ;
1317
                        else if ( code > 0xFF )
1318
                                n += fprintf( f, "    %04X  ", code & 0xFFFF ) ;
1319
                        else
1320
                                n += fprintf( f, "      %02X  ", code & 0xFF ) ;
1321
                } else {
1322
                        if ( addr != 0xFFFFFFFF ) {
1323
                                // address info
1324
                                n += fprintf( f, "%03X       ", addr ) ;
1325
                        } else
1326
                                n += fprintf( f, "          " ) ;
1327
                }
1328
        }
1329
 
1330
        if ( tok_current()->type == tLABEL ) {
1331
                // labels in the margin
1332
                n += fprintf( f, "%*s", -16, tok_next()->text ) ;
1333
                n += fprintf( f, "%s", tok_next()->text ) ;
1334
        } else if ( tok_current()->subtype == stEQU ) {
1335
                // print EQUates in the label margin
1336
                n += fprintf( f, "%*s", -( 16 + 1 ), tok_next()->text ) ;
1337
        } else if ( tok_current()->type != tNONE )
1338
                // else print a blank margin
1339
                n += fprintf( f, "%*s", 16 + 1, "" ) ;
1340
 
1341
        // opcode
1342
        if ( tok_current()->type != tNONE && tok_current()->text != NULL ) {
1343
                for ( s = tok_current()->text ; s != NULL && isalpha( *s ) ; s++ )
1344
                        *s = toupper( *s ) ;
1345
                n += fprintf( f, " %*s", -6, tok_next()->text ) ;
1346
        }
1347
 
1348
        // operand
1349
        for ( ; tok_current()->type != tNONE ; tok_next() ) {
1350
                if ( tok_current()->text != NULL ) {
1351
                        if ( tok_current()->type != tCOMMA )
1352
                                n += fprintf( f, " " ) ;
1353
                        switch ( tok_current()->type ) {
1354
                        case tHEX :
1355
                                n += fprintf( f, "0x%s", tok_current()->text ) ;
1356
                                break ;
1357
                        case tBIN :
1358
                                n += fprintf( f, "0b%s", tok_current()->text ) ;
1359
                                break ;
1360
                        case tCHAR :
1361
                                n += fprintf( f, "'%s'", tok_current()->text ) ;
1362
                                break ;
1363
                        case tSTRING :
1364
                                n += fprintf( f, "\"%s\"", tok_current()->text ) ;
1365
                                break ;
1366
                        default :
1367
                                n += fprintf( f, "%s", tok_current()->text ) ;
1368
                                break ;
1369
                        }
1370
                }
1371
        }
1372
 
1373
        // comment
1374
        if ( tok_current()->type == tNONE && tok_current()->subtype == stCOMMENT ) {
1375
                if ( tok_current()->text != NULL ) {
1376
                        if ( n <= 10 )
1377
                                // at the start
1378
                                fprintf( f, "%s", tok_current()->text ) ;
1379
                        else if ( n < 60 ) {
1380
                                // at column 60
1381
                                fprintf( f, "%*s", 60 - n, "" ) ;
1382
                                fprintf( f, "%s", tok_current()->text ) ;
1383
                        } else
1384
                                // after the rest
1385
                                fprintf( f, " %s", tok_current()->text ) ;
1386
                }
1387
        }
1388
        fprintf( f, "\n" ) ;
1389
}
1390
 
1391
// main entry for the 2-pass assembler
1392
bool assembler( char ** sourcefilenames, char * codefilename, char * listfilename, bool mode, bool listcode, bool hex, bool zeros ) {
1393
        FILE * fsrc = NULL ;
1394
        FILE * fmem = NULL ;
1395
        FILE * flist = NULL ;
1396
        char ** Sources = NULL ;
1397
        char line[ 256 ] ;
1398
        error_t e = etNONE ;
1399
        int h = 0 ;
1400
        bool result = true ;
1401
 
1402
        uint32_t addr, code ;
1403
 
1404
        // set up symbol table with keywords
1405
        init_symbol() ;
1406
 
1407
        // clear code
1408
        for ( h = 0 ; h < 1024 + 256 / 2 ; h += 1 )
1409
                gCode[ h ] = 0xFFFC0000 ;
1410
 
1411
        Sources = sourcefilenames ;
1412
        gPC = 0 ;
1413
        gSCR = 2048 ;
1414
        bMode = mode ;
1415
        for ( gSource = *Sources++ ; gSource != NULL ; gSource = *Sources++ ) {
1416
                // open source file
1417
                fsrc = fopen( gSource, "r" ) ;
1418
                if ( fsrc == NULL ) {
1419
                        fprintf( stderr, "? unable to open source file '%s'", gSource ) ;
1420
                        result = false ;
1421
                        goto finally ;
1422
                }
1423
 
1424
                // pass 1, add symbols from source
1425
                for ( gLinenr = 1 ; fgets( line, sizeof( line ), fsrc ) != NULL ; gLinenr += 1 ) {
1426
                        if ( lex( line, mode ) ) {
1427
                                result &= error( build() ) ;
1428
                                tok_free() ;
1429
                        } else {
1430
                                result &= error( etLEX ) ;
1431
                        }
1432
                }
1433
                fclose( fsrc ) ;
1434
        }
1435
 
1436
        // give up if errors in pass 1
1437
        if ( !result )
1438
                goto finally ;
1439
 
1440
        if ( strlen( listfilename ) > 0 ) {
1441
                flist = fopen( listfilename, "w" ) ;
1442
                if ( flist == NULL ) {
1443
                        fprintf( stderr, "? unable to create LST file '%s'", listfilename ) ;
1444
                        result = false ;
1445
                }
1446
        }
1447
 
1448
        bCode = listcode ;
1449
        Sources = sourcefilenames ;
1450
        for ( gSource = *Sources++, gPC = 0, gSCR = 2048, bMode = mode ; gSource != NULL ; gSource = *Sources++ ) {
1451
 
1452
                fsrc = fopen( gSource, "r" ) ;
1453
                if ( fsrc == NULL ) {
1454
                        fprintf( stderr, "? unable to re-open source file '%s'", gSource ) ;
1455
                        result = false ;
1456
                        goto finally ;
1457
                }
1458
 
1459
                // pass 2, build code and scratchpad
1460
                for ( gLinenr = 1 ; fgets( line, sizeof( line ), fsrc ) != NULL ; gLinenr += 1 ) {
1461
                        if ( lex( line, mode ) ) {
1462
                                result &= error( e = assemble( &addr, &code ) ) ;
1463
                                if ( flist != NULL )
1464
                                        print_line( flist, e, addr, code ) ;
1465
                        } else {
1466
                                result &= error( etLEX ) ;
1467
                                if ( flist != NULL )
1468
                                        print_line( flist, etLEX, 0xFFFFFFFF, 0xFFFFFFFF ) ;
1469
                        }
1470
                        tok_free() ;
1471
                }
1472
                fclose( fsrc ) ;
1473
        }
1474
 
1475
        // dump code and scratch pad
1476
        if ( strlen( codefilename ) > 0 ) {
1477
                fmem = fopen( codefilename, "w" ) ;
1478
                if ( fmem == NULL ) {
1479
                        fprintf( stderr, "? unable to create MEM file '%s'", codefilename ) ;
1480
                        result = false ;
1481
                } else {
1482
                        dump_code( fmem, hex, zeros ) ;
1483
                        fclose( fmem ) ;
1484
                }
1485
        }
1486
 
1487
        finally: {
1488
                if ( flist != NULL )
1489
                        fclose( flist ) ;
1490
                free_symbol() ;
1491
        }
1492
 
1493
        return result ;
1494
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.