2021-01-29 15:14:37 -05:00
# include <stdio.h>
/*
Copyright ( c ) 2021 Devine Lu Linvega
Permission to use , copy , modify , and distribute this software for any
purpose with or without fee is hereby granted , provided that the above
copyright notice and this permission notice appear in all copies .
THE SOFTWARE IS PROVIDED " AS IS " AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE .
*/
typedef unsigned char Uint8 ;
2021-02-12 19:18:52 -05:00
typedef signed char Sint8 ;
2021-02-04 15:22:08 -05:00
typedef unsigned short Uint16 ;
2021-02-12 19:18:52 -05:00
typedef signed short Sint16 ;
2021-01-29 15:14:37 -05:00
2021-03-14 16:30:17 -04:00
typedef struct {
char name [ 64 ] , items [ 16 ] [ 64 ] ;
2021-03-14 17:26:17 -04:00
Uint8 len , refs ;
2021-03-14 16:30:17 -04:00
} Macro ;
2021-03-13 23:51:43 -05:00
typedef struct {
2021-03-13 20:34:08 -05:00
char name [ 64 ] ;
unsigned int size ;
} Map ;
2021-02-23 01:15:02 -05:00
2021-01-31 00:31:49 -05:00
typedef struct {
2021-03-13 17:55:29 -05:00
char name [ 64 ] ;
2021-03-13 23:51:43 -05:00
Uint8 refs , maps ;
2021-03-21 13:38:46 -04:00
Uint16 addr , len ;
2021-03-13 20:34:08 -05:00
Map map [ 16 ] ;
2021-01-31 00:31:49 -05:00
} Label ;
2021-03-13 17:55:29 -05:00
typedef struct {
2021-03-14 16:30:17 -04:00
Uint8 data [ 256 * 256 ] , llen , mlen ;
2021-03-21 17:16:19 -04:00
Uint16 ptr ;
2021-03-13 17:55:29 -05:00
Label labels [ 256 ] ;
2021-03-14 16:30:17 -04:00
Macro macros [ 256 ] ;
2021-03-13 17:55:29 -05:00
} Program ;
2021-02-23 01:15:02 -05:00
2021-02-07 13:21:41 -05:00
Program p ;
2021-01-30 17:25:48 -05:00
2021-02-01 23:21:27 -05:00
/* clang-format off */
2021-02-06 13:39:13 -05:00
char ops [ ] [ 4 ] = {
2021-03-21 14:04:20 -04:00
" BRK " , " NOP " , " LIT " , " POP " , " DUP " , " SWP " , " OVR " , " ROT " ,
2021-03-26 23:16:48 -04:00
" EQU " , " NEQ " , " GTH " , " LTH " , " GTS " , " LTS " , " --- " , " --- " ,
" PEK " , " POK " , " LDR " , " STR " , " JMP " , " JNZ " , " JSR " , " STH " ,
2021-03-21 13:24:44 -04:00
" ADD " , " SUB " , " MUL " , " DIV " , " AND " , " ORA " , " EOR " , " SFT "
2021-02-04 15:22:08 -05:00
} ;
2021-02-01 23:21:27 -05:00
2021-02-23 14:10:49 -05:00
int scin ( char * s , char c ) { int i = 0 ; while ( s [ i ] ) if ( s [ i + + ] = = c ) return i - 1 ; return - 1 ; } /* string char index */
int scmp ( char * a , char * b , int len ) { int i = 0 ; while ( a [ i ] = = b [ i ] & & i < len ) if ( ! a [ i + + ] ) return 1 ; return 0 ; } /* string compare */
int slen ( char * s ) { int i = 0 ; while ( s [ i ] & & s [ + + i ] ) ; return i ; } /* string length */
int sihx ( char * s ) { int i = 0 ; char c ; while ( ( c = s [ i + + ] ) ) if ( ! ( c > = ' 0 ' & & c < = ' 9 ' ) & & ! ( c > = ' a ' & & c < = ' f ' ) & & ! ( c > = ' A ' & & c < = ' F ' ) ) return 0 ; return 1 ; } /* string is hexadecimal */
int shex ( char * s ) { int n = 0 , i = 0 ; char c ; while ( ( c = s [ i + + ] ) ) if ( c > = ' 0 ' & & c < = ' 9 ' ) n = n * 16 + ( c - ' 0 ' ) ; else if ( c > = ' A ' & & c < = ' F ' ) n = n * 16 + 10 + ( c - ' A ' ) ; else if ( c > = ' a ' & & c < = ' f ' ) n = n * 16 + 10 + ( c - ' a ' ) ; return n ; } /* string to num */
2021-02-07 13:21:41 -05:00
char * scpy ( char * src , char * dst , int len ) { int i = 0 ; while ( ( dst [ i ] = src [ i ] ) & & i < len - 2 ) i + + ; dst [ i + 1 ] = ' \0 ' ; return dst ; } /* string copy */
2021-01-29 16:59:16 -05:00
# pragma mark - Helpers
2021-02-07 13:21:41 -05:00
/* clang-format on */
2021-01-30 17:25:48 -05:00
2021-02-04 15:22:08 -05:00
# pragma mark - I / O
2021-02-01 23:21:27 -05:00
void
2021-02-04 15:22:08 -05:00
pushbyte ( Uint8 b , int lit )
2021-02-01 23:21:27 -05:00
{
2021-03-13 17:55:29 -05:00
if ( lit ) pushbyte ( 0x02 , 0 ) ;
2021-02-04 15:22:08 -05:00
p . data [ p . ptr + + ] = b ;
2021-02-01 23:21:27 -05:00
}
void
2021-02-04 15:22:08 -05:00
pushshort ( Uint16 s , int lit )
2021-02-01 23:21:27 -05:00
{
2021-03-13 17:55:29 -05:00
if ( lit ) pushbyte ( 0x22 , 0 ) ;
2021-02-04 15:22:08 -05:00
pushbyte ( ( s > > 8 ) & 0xff , 0 ) ;
pushbyte ( s & 0xff , 0 ) ;
2021-02-01 23:21:27 -05:00
}
2021-02-23 16:49:36 -05:00
void
pushtext ( char * s , int lit )
{
int i = 0 ;
char c ;
2021-03-13 17:55:29 -05:00
if ( lit ) pushbyte ( 0x22 , 0 ) ;
while ( ( c = s [ i + + ] ) ) pushbyte ( c , 0 ) ;
2021-02-23 16:49:36 -05:00
}
2021-03-14 16:30:17 -04:00
Macro *
findmacro ( char * name )
{
int i ;
for ( i = 0 ; i < p . mlen ; + + i )
if ( scmp ( p . macros [ i ] . name , name , 64 ) )
return & p . macros [ i ] ;
return NULL ;
}
2021-01-31 00:31:49 -05:00
Label *
2021-02-23 15:04:59 -05:00
findlabel ( char * s )
2021-01-31 00:31:49 -05:00
{
2021-02-23 15:04:59 -05:00
int i , rng = scin ( s , ' . ' ) ;
char name [ 64 ] ;
scpy ( s , name , rng > 0 ? rng + 1 : 64 ) ;
2021-03-13 17:55:29 -05:00
for ( i = 0 ; i < p . llen ; + + i )
if ( scmp ( p . labels [ i ] . name , name , 64 ) )
return & p . labels [ i ] ;
2021-01-31 00:31:49 -05:00
return NULL ;
}
2021-02-23 15:04:59 -05:00
Uint16
findlabeladdr ( char * s )
2021-02-23 14:10:49 -05:00
{
2021-02-23 15:04:59 -05:00
int i , o = 0 ;
char * param ;
Label * l = findlabel ( s ) ;
if ( scin ( s , ' . ' ) < 1 )
return l - > addr ;
param = s + scin ( s , ' . ' ) + 1 ;
2021-03-13 20:34:08 -05:00
for ( i = 0 ; i < l - > maps ; + + i ) {
if ( scmp ( l - > map [ i ] . name , param , 64 ) )
2021-02-23 15:04:59 -05:00
return l - > addr + o ;
2021-03-13 20:34:08 -05:00
o + = l - > map [ i ] . size ;
2021-02-23 14:10:49 -05:00
}
2021-03-13 20:34:08 -05:00
printf ( " !!! Warning %s.%s \n " , l - > name , param ) ;
2021-02-23 15:04:59 -05:00
return 0 ;
2021-02-23 14:10:49 -05:00
}
2021-02-23 15:04:59 -05:00
Uint8
findlabellen ( char * s )
2021-02-23 14:10:49 -05:00
{
2021-02-23 15:04:59 -05:00
int i ;
char * param ;
Label * l = findlabel ( s ) ;
if ( scin ( s , ' . ' ) < 1 )
2021-03-13 23:51:43 -05:00
return l - > map [ 0 ] . size ;
2021-02-23 15:04:59 -05:00
param = s + scin ( s , ' . ' ) + 1 ;
2021-03-13 20:34:08 -05:00
for ( i = 0 ; i < l - > maps ; + + i )
if ( scmp ( l - > map [ i ] . name , param , 64 ) )
return l - > map [ i ] . size ;
printf ( " !!! Warning %s.%s \n " , l - > name , param ) ;
2021-02-23 15:04:59 -05:00
return 0 ;
2021-02-23 14:10:49 -05:00
}
2021-02-06 13:39:13 -05:00
Uint8
2021-02-13 16:21:05 -05:00
findopcode ( char * s )
2021-02-06 13:39:13 -05:00
{
int i ;
2021-02-07 13:21:41 -05:00
for ( i = 0 ; i < 0x20 ; + + i ) {
2021-02-06 13:39:13 -05:00
int m = 0 ;
2021-02-07 13:21:41 -05:00
char * o = ops [ i ] ;
if ( o [ 0 ] ! = s [ 0 ] | | o [ 1 ] ! = s [ 1 ] | | o [ 2 ] ! = s [ 2 ] )
continue ;
2021-02-06 13:39:13 -05:00
while ( s [ 3 + m ] ) {
2021-03-27 14:04:05 -04:00
if ( s [ 3 + m ] = = ' 2 ' )
i | = ( 1 < < 5 ) ; /* mode: short */
else if ( s [ 3 + m ] = = ' r ' )
i | = ( 1 < < 6 ) ; /* mode: return */
else
return 0 ; /* failed to match */
2021-02-06 13:39:13 -05:00
m + + ;
}
return i ;
}
return 0 ;
}
2021-03-11 18:47:28 -05:00
char *
sublabel ( char * src , char * scope , char * name )
{
scpy ( scope , src , 64 ) ;
scpy ( " - " , src + slen ( src ) , 64 ) ;
scpy ( name , src + slen ( src ) , 64 ) ;
return src ;
}
2021-02-04 15:22:08 -05:00
# pragma mark - Parser
2021-01-31 00:31:49 -05:00
2021-01-30 17:25:48 -05:00
int
2021-02-04 15:22:08 -05:00
error ( char * name , char * id )
2021-01-30 17:25:48 -05:00
{
2021-02-05 23:18:30 -05:00
printf ( " Error: %s[%s] \n " , name , id ) ;
2021-02-04 16:49:03 -05:00
return 0 ;
}
2021-03-14 16:30:17 -04:00
int
makemacro ( char * name , FILE * f )
{
Macro * m ;
char word [ 64 ] ;
if ( findmacro ( name ) )
return error ( " Macro duplicate " , name ) ;
if ( sihx ( name ) & & slen ( name ) % 2 = = 0 )
return error ( " Macro name is hex number " , name ) ;
if ( findopcode ( name ) )
return error ( " Macro name is invalid " , name ) ;
m = & p . macros [ p . mlen + + ] ;
scpy ( name , m - > name , 64 ) ;
while ( fscanf ( f , " %s " , word ) ) {
if ( word [ 0 ] = = ' { ' ) continue ;
if ( word [ 0 ] = = ' } ' ) break ;
scpy ( word , m - > items [ m - > len + + ] , 64 ) ;
}
printf ( " New macro: %s(%d items) \n " , m - > name , m - > len ) ;
return 1 ;
}
2021-02-23 01:15:02 -05:00
int
2021-03-13 20:34:08 -05:00
makelabel ( char * name , Uint16 addr )
2021-02-04 16:49:03 -05:00
{
Label * l ;
2021-02-07 13:21:41 -05:00
if ( findlabel ( name ) )
return error ( " Label duplicate " , name ) ;
2021-03-11 15:19:59 -05:00
if ( sihx ( name ) & & slen ( name ) % 2 = = 0 )
2021-02-12 19:18:52 -05:00
return error ( " Label name is hex number " , name ) ;
2021-02-13 16:21:05 -05:00
if ( findopcode ( name ) )
2021-02-13 11:38:23 -05:00
return error ( " Label name is invalid " , name ) ;
2021-03-13 17:55:29 -05:00
l = & p . labels [ p . llen + + ] ;
2021-02-04 16:49:03 -05:00
l - > addr = addr ;
2021-03-01 12:16:40 -05:00
l - > refs = 0 ;
2021-02-07 13:21:41 -05:00
scpy ( name , l - > name , 64 ) ;
2021-03-13 23:51:43 -05:00
printf ( " New label: %s, at 0x%04x \n " , l - > name , l - > addr ) ;
2021-02-04 16:49:03 -05:00
return 1 ;
}
2021-02-10 19:41:16 -05:00
int
2021-03-13 20:34:08 -05:00
makevariable ( char * name , Uint16 * addr , FILE * f )
2021-02-10 19:41:16 -05:00
{
2021-03-13 20:34:08 -05:00
Label * l ;
char word [ 64 ] ;
if ( ! makelabel ( name , * addr ) )
return error ( " Could not create variable " , name ) ;
l = findlabel ( name ) ;
while ( fscanf ( f , " %s " , word ) ) {
if ( word [ 0 ] = = ' { ' ) continue ;
if ( word [ 0 ] = = ' } ' ) break ;
scpy ( word , l - > map [ l - > maps ] . name , 64 ) ;
fscanf ( f , " %u " , & l - > map [ l - > maps ] . size ) ;
2021-03-21 13:38:46 -04:00
* addr + = l - > map [ l - > maps ] . size ;
l - > len + = l - > map [ l - > maps + + ] . size ;
2021-03-13 20:34:08 -05:00
}
return 1 ;
2021-02-10 19:41:16 -05:00
}
2021-02-13 19:37:03 -05:00
int
2021-02-23 01:15:02 -05:00
skipblock ( char * w , int * cap , char a , char b )
2021-02-15 17:04:58 -05:00
{
2021-02-23 01:15:02 -05:00
if ( w [ 0 ] = = b ) {
2021-02-15 17:04:58 -05:00
* cap = 0 ;
return 1 ;
}
2021-02-23 01:15:02 -05:00
if ( w [ 0 ] = = a ) * cap = 1 ;
2021-02-15 17:04:58 -05:00
if ( * cap ) return 1 ;
return 0 ;
}
2021-03-14 16:30:17 -04:00
int
walktoken ( char * w )
{
Macro * m ;
if ( findopcode ( w ) | | scmp ( w , " BRK " , 4 ) )
return 1 ;
switch ( w [ 0 ] ) {
2021-03-28 13:20:24 -04:00
case ' = ' : return 4 - ( findlabel ( w + 1 ) & & findlabeladdr ( w + 1 ) < 0x0100 ) ; /* POK/STR helper (lit addr(1/2) str) */
case ' ~ ' : return 4 - ( findlabel ( w + 1 ) & & findlabeladdr ( w + 1 ) < 0x0100 ) ; /* PEK/LDR helper (lit addr(1/2) ldr) */
case ' , ' : return 3 ; /* lit2 addr-hb addr-lb */
case ' . ' : return 2 ; /* addr-hb addr-lb */
case ' ^ ' : return 2 ; /* Relative jump: lit addr-offset */
2021-03-14 16:30:17 -04:00
case ' # ' : return ( slen ( w + 1 ) = = 2 ? 2 : 3 ) ;
}
2021-03-14 16:47:09 -04:00
if ( ( m = findmacro ( w ) ) ) {
int i , res = 0 ;
for ( i = 0 ; i < m - > len ; + + i )
res + = walktoken ( m - > items [ i ] ) ;
return res ;
}
2021-03-14 16:30:17 -04:00
return error ( " Unknown label in first pass " , w ) ;
}
int
parsetoken ( char * w )
{
Uint8 op = 0 ;
Label * l ;
Macro * m ;
if ( w [ 0 ] = = ' ^ ' & & ( l = findlabel ( w + 1 ) ) ) {
int off = l - > addr - p . ptr - 3 ;
if ( off < - 126 | | off > 126 ) {
printf ( " Address %s is too far(%d). \n " , w , off ) ;
return 0 ;
}
pushbyte ( ( Sint8 ) ( l - > addr - p . ptr - 3 ) , 1 ) ;
l - > refs + + ;
return 1 ;
2021-03-14 16:47:09 -04:00
} else if ( w [ 0 ] = = ' = ' & & ( l = findlabel ( w + 1 ) ) ) {
2021-03-14 16:30:17 -04:00
if ( ! findlabellen ( w + 1 ) | | findlabellen ( w + 1 ) > 2 )
2021-03-14 16:47:09 -04:00
return error ( " Invalid store helper " , w ) ;
2021-03-28 12:48:00 -04:00
if ( findlabeladdr ( w + 1 ) < 0x0100 ) {
pushbyte ( findlabeladdr ( w + 1 ) , 1 ) ;
pushbyte ( findopcode ( findlabellen ( w + 1 ) = = 2 ? " STR " : " POK " ) , 0 ) ;
} else {
pushshort ( findlabeladdr ( w + 1 ) , 1 ) ;
pushbyte ( findopcode ( findlabellen ( w + 1 ) = = 2 ? " STR2 " : " POK2 " ) , 0 ) ;
}
2021-03-14 16:30:17 -04:00
l - > refs + + ;
return 1 ;
2021-03-14 16:47:09 -04:00
} else if ( w [ 0 ] = = ' ~ ' & & ( l = findlabel ( w + 1 ) ) ) {
2021-03-14 16:30:17 -04:00
if ( ! findlabellen ( w + 1 ) | | findlabellen ( w + 1 ) > 2 )
return error ( " Invalid load helper " , w ) ;
2021-03-28 12:48:00 -04:00
if ( findlabeladdr ( w + 1 ) < 0x0100 ) {
pushbyte ( findlabeladdr ( w + 1 ) , 1 ) ;
pushbyte ( findopcode ( findlabellen ( w + 1 ) = = 2 ? " LDR " : " PEK " ) , 0 ) ;
} else {
pushshort ( findlabeladdr ( w + 1 ) , 1 ) ;
pushbyte ( findopcode ( findlabellen ( w + 1 ) = = 2 ? " LDR2 " : " PEK2 " ) , 0 ) ;
}
2021-03-14 16:30:17 -04:00
l - > refs + + ;
return 1 ;
2021-03-14 16:47:09 -04:00
} else if ( ( op = findopcode ( w ) ) | | scmp ( w , " BRK " , 4 ) ) {
2021-03-14 16:30:17 -04:00
pushbyte ( op , 0 ) ;
return 1 ;
2021-03-14 16:47:09 -04:00
} else if ( w [ 0 ] = = ' . ' & & ( l = findlabel ( w + 1 ) ) ) {
2021-03-14 16:30:17 -04:00
pushshort ( findlabeladdr ( w + 1 ) , 0 ) ;
l - > refs + + ;
return 1 ;
2021-03-14 16:47:09 -04:00
} else if ( w [ 0 ] = = ' , ' & & ( l = findlabel ( w + 1 ) ) ) {
2021-03-14 16:30:17 -04:00
pushshort ( findlabeladdr ( w + 1 ) , 1 ) ;
l - > refs + + ;
return 1 ;
2021-03-14 16:47:09 -04:00
} else if ( w [ 0 ] = = ' # ' & & sihx ( w + 1 ) ) {
2021-03-14 16:30:17 -04:00
if ( slen ( w + 1 ) = = 2 )
pushbyte ( shex ( w + 1 ) , 1 ) ;
else if ( slen ( w + 1 ) = = 4 )
pushshort ( shex ( w + 1 ) , 1 ) ;
else
return 0 ;
return 1 ;
2021-03-14 16:47:09 -04:00
} else if ( ( m = findmacro ( w ) ) ) {
int i ;
2021-03-14 20:41:52 -04:00
m - > refs + + ;
2021-03-14 16:47:09 -04:00
for ( i = 0 ; i < m - > len ; + + i )
2021-03-14 16:30:17 -04:00
if ( ! parsetoken ( m - > items [ i ] ) )
return 0 ;
return 1 ;
}
return 0 ;
}
2021-02-04 00:53:56 -05:00
int
2021-01-29 15:14:37 -05:00
pass1 ( FILE * f )
{
2021-02-23 16:49:36 -05:00
int ccmnt = 0 , cbits = 0 ;
2021-02-04 18:23:04 -05:00
Uint16 addr = 0 ;
2021-03-11 18:47:28 -05:00
char w [ 64 ] , scope [ 64 ] , subw [ 64 ] ;
2021-02-23 14:10:49 -05:00
printf ( " Pass 1 \n " ) ;
2021-02-04 15:22:08 -05:00
while ( fscanf ( f , " %s " , w ) = = 1 ) {
2021-02-23 01:15:02 -05:00
if ( skipblock ( w , & ccmnt , ' ( ' , ' ) ' ) ) continue ;
2021-02-23 16:49:36 -05:00
if ( skipblock ( w , & cbits , ' [ ' , ' ] ' ) ) {
if ( w [ 0 ] = = ' [ ' | | w [ 0 ] = = ' ] ' )
continue ;
2021-03-21 13:42:50 -04:00
if ( slen ( w ) = = 4 & & sihx ( w ) )
addr + = 2 ;
else if ( slen ( w ) = = 2 & & sihx ( w ) )
addr + = 1 ;
2021-03-01 12:38:54 -05:00
else
2021-03-05 15:02:01 -05:00
addr + = slen ( w ) ;
2021-03-14 16:30:17 -04:00
} else if ( w [ 0 ] = = ' % ' ) {
if ( ! makemacro ( w + 1 , f ) )
return error ( " Pass1 failed " , w ) ;
scpy ( w + 1 , scope , 64 ) ;
2021-02-23 16:49:36 -05:00
} else if ( w [ 0 ] = = ' @ ' ) {
2021-03-13 20:34:08 -05:00
if ( ! makelabel ( w + 1 , addr ) )
2021-02-10 19:41:16 -05:00
return error ( " Pass1 failed " , w ) ;
2021-03-11 18:47:28 -05:00
scpy ( w + 1 , scope , 64 ) ;
} else if ( w [ 0 ] = = ' $ ' ) {
2021-03-13 20:34:08 -05:00
if ( ! makelabel ( sublabel ( subw , scope , w + 1 ) , addr ) )
2021-03-11 18:47:28 -05:00
return error ( " Pass1 failed " , w ) ;
2021-02-10 19:41:16 -05:00
} else if ( w [ 0 ] = = ' ; ' ) {
if ( ! makevariable ( w + 1 , & addr , f ) )
return error ( " Pass1 failed " , w ) ;
2021-03-14 16:30:17 -04:00
} else if ( w [ 0 ] = = ' | ' ) {
if ( shex ( w + 1 ) < addr )
return error ( " Memory Overwrite " , w ) ;
addr = shex ( w + 1 ) ;
2021-03-14 16:47:09 -04:00
} else
2021-03-14 16:30:17 -04:00
addr + = walktoken ( w ) ;
2021-01-30 17:25:48 -05:00
}
rewind ( f ) ;
2021-02-04 15:22:08 -05:00
return 1 ;
2021-01-30 17:25:48 -05:00
}
2021-02-04 15:22:08 -05:00
int
2021-01-30 17:25:48 -05:00
pass2 ( FILE * f )
{
2021-03-13 13:31:29 -05:00
int ccmnt = 0 , cbits = 0 , ctemplate = 0 ;
2021-03-11 18:47:28 -05:00
char w [ 64 ] , scope [ 64 ] , subw [ 64 ] ;
2021-02-23 14:10:49 -05:00
printf ( " Pass 2 \n " ) ;
2021-02-04 15:22:08 -05:00
while ( fscanf ( f , " %s " , w ) = = 1 ) {
2021-03-11 18:47:28 -05:00
if ( w [ 0 ] = = ' $ ' ) continue ;
2021-03-14 16:30:17 -04:00
if ( w [ 0 ] = = ' % ' ) continue ;
2021-03-13 17:55:29 -05:00
if ( skipblock ( w , & ccmnt , ' ( ' , ' ) ' ) ) continue ;
if ( skipblock ( w , & ctemplate , ' { ' , ' } ' ) ) continue ;
2021-03-21 13:38:46 -04:00
if ( w [ 0 ] = = ' ; ' ) {
p . ptr + = findlabel ( w + 1 ) - > len ;
continue ;
}
2021-03-14 16:30:17 -04:00
if ( w [ 0 ] = = ' | ' ) {
p . ptr = shex ( w + 1 ) ;
continue ;
}
2021-03-11 18:47:28 -05:00
if ( w [ 0 ] = = ' @ ' ) {
scpy ( w + 1 , scope , 64 ) ;
continue ;
}
if ( w [ 1 ] = = ' $ ' ) {
2021-03-14 16:30:17 -04:00
scpy ( sublabel ( subw , scope , w + 2 ) , w + 1 , 64 ) ;
2021-03-11 18:47:28 -05:00
}
2021-02-23 16:49:36 -05:00
if ( skipblock ( w , & cbits , ' [ ' , ' ] ' ) ) {
if ( w [ 0 ] = = ' [ ' | | w [ 0 ] = = ' ] ' ) { continue ; }
2021-03-14 16:30:17 -04:00
if ( slen ( w ) = = 4 & & sihx ( w ) )
pushshort ( shex ( w ) , 0 ) ;
else if ( slen ( w ) = = 2 & & sihx ( w ) )
pushbyte ( shex ( w ) , 0 ) ;
else
pushtext ( w , 0 ) ;
} else if ( ! parsetoken ( w ) ) {
return error ( " Unknown label in second pass " , w ) ;
2021-03-11 15:19:59 -05:00
}
2021-01-29 15:14:37 -05:00
}
2021-02-04 15:22:08 -05:00
return 1 ;
2021-01-29 15:14:37 -05:00
}
2021-03-01 12:16:40 -05:00
void
2021-03-13 20:34:08 -05:00
cleanup ( char * filename )
2021-03-01 12:16:40 -05:00
{
int i ;
2021-03-21 17:16:19 -04:00
printf ( " Assembled %s(%0.2fkb), %d labels, %d macros. \n \n " , filename , p . ptr / 1000.0 , p . llen , p . mlen ) ;
2021-03-13 17:55:29 -05:00
for ( i = 0 ; i < p . llen ; + + i )
if ( ! p . labels [ i ] . refs )
printf ( " --- Unused label: %s \n " , p . labels [ i ] . name ) ;
2021-03-14 17:26:17 -04:00
for ( i = 0 ; i < p . mlen ; + + i )
if ( ! p . macros [ i ] . refs )
printf ( " --- Unused macro: %s \n " , p . macros [ i ] . name ) ;
2021-03-01 12:16:40 -05:00
}
2021-01-29 15:14:37 -05:00
int
main ( int argc , char * argv [ ] )
{
FILE * f ;
2021-03-16 12:01:47 -04:00
if ( argc < 3 ) {
error ( " Input " , " Missing " ) ;
return 1 ;
}
if ( ! ( f = fopen ( argv [ 1 ] , " r " ) ) ) {
error ( " Open " , " Failed " ) ;
return 1 ;
}
if ( ! pass1 ( f ) | | ! pass2 ( f ) ) {
error ( " Assembly " , " Failed " ) ;
return 1 ;
}
2021-03-21 17:16:19 -04:00
fwrite ( p . data , p . ptr , 1 , fopen ( argv [ 2 ] , " wb " ) ) ;
2021-01-29 16:59:16 -05:00
fclose ( f ) ;
2021-03-13 20:34:08 -05:00
cleanup ( argv [ 2 ] ) ;
2021-01-29 15:14:37 -05:00
return 0 ;
}