#!/bin/perl # Armpi3 assembly source to BASIC converter. # Usage: s2bas <source_file> # Tab characters must be converted to spaces. This is automatically done if # the output is sent to a taskwindow and if you save the content to a file. while (<>) { &conv($_) } die "WHILE without WEND\n" if ($wh ne ''); print "DIM code% 2048, D% 13\n",$rn; print <<EOF; LR=14 FOR pass%=0 TO 2 STEP 2 P%=code% [ OPT pass% .calpi STMFD R13!, {R0, R1, R3, LR} MOV R0, #1 MOV R1, R3 SWI "OS_Word" LDMFD R13, {R0, R1} BL start MOV R0, #1 LDR R1, [SP, #8] ADD R1, R1, #8 SWI "OS_Word" LDMFD R13!, {R0, R2, R3} ADD R3, R0, R2 .calpi_loop LDR R0, [R3, #-1]! ORR R0, R0, #&30 SWI "OS_WriteC" CMP R2, R3 BNE calpi_loop SWI &10D SWI &10A LDR PC, [SP], #4 $out] NEXT \@%="G0" INPUT A% IF A% < 4 THEN END DIM B% 4*((29*A%) DIV 48)+1548 IF A% MOD 4 = 0 THEN CALL calpi : PRINT "Temps = "(D%!8-D%!0)/100" s." EOF sub conv { $_ = $_[0]; if ($wh ne '' && /^\s+WEND\s+/) { $ww = 1; while (eval $wh) { foreach (@wh) { conv($_) } } ($wh, $ww, @wh) = (); } elsif ($wh ne '' && !$ww) { push @wh, $_ } elsif (/^(\w*)\s+\[\s+(.+)/) { die "| or ] expected\n" if ($if); $out .= ".$1\n" if ($1 ne ''); ($expr = $2) =~ s/\b([A-Za-z_]\w*)/\$$1/go; $cond = eval $expr; $if = 1; } elsif (/^(\w*)\s+\|\s+/) { $out .= ".$1\n" if ($1 ne '' && $cond); $cond = !$cond; } elsif (/^(\w*)\s+]\s+/) { $out .= ".$1\n" if ($1 ne '' && $cond); $if = ''; } elsif (!$if || $cond) { if (substr($_,0,1) eq ';') { $out .= 'REM'.substr($_,1) } elsif (/^(\w+)\s+RN\s+(\d+)/o) { $rn .= "$1=$2\n"; $reg{$1} = "R$2"; } elsif (/^(\w*)\s+GBLA\s+(\w+)/o) { eval "\$$2=0" } elsif (($var,$expr) = /^(\w+)\s+SETA\s+(.+)/o) { $expr =~ s/\b([A-Za-z_]\w*)/\$$1/go; eval "\$$var=$expr"; } elsif (/^(\w*)\s+WHILE\s+(.+)/o) { die "WEND expected\n" if ($wh ne ''); $out .= ".$1\n" if ($1 ne ''); ($wh = $2) =~ s/\b([A-Za-z_]\w*)/\$$1/go; } elsif (/^(\w+)(\s+)(DC.\s+)(.+?),(.+)\n/) { $out .= ".$1".(substr($2,0,1) eq ' ' ? substr($2,1) : $2)."$3$4\n"; foreach (split /,/, $5) { $out .= "\t\t$3$_\n" } } elsif (/^(\w*)\s+ADR\s+(\w+)\s*,\s*(\w+)\s+$/) { $out .= ".$1\n" if ($1 ne ''); $adrn = 'adr'.++$adr; $out .= ".$adrn\t\tADD\t$2, PC, #(($3-$adrn-8)DIV64)*64\n\t\tADD\t$2, $2, #(($3-$adrn-8)MOD64)\n"; } else { s/(\w+)!/$reg{$1}!/; $out .= /^(\w+)(\s*)(.*\n)/o ? ".$1".(substr($2,0,1) eq ' ' ? substr($2,1) : $2).$3 : $_ } } }