diff --git a/src/ca65html/.cvsignore b/src/ca65html/.cvsignore new file mode 100644 index 000000000..f07c30f94 --- /dev/null +++ b/src/ca65html/.cvsignore @@ -0,0 +1,2 @@ +*.html +*.s diff --git a/src/ca65html/ca65html b/src/ca65html/ca65html new file mode 100755 index 000000000..6961c8eb4 --- /dev/null +++ b/src/ca65html/ca65html @@ -0,0 +1,261 @@ +#!/usr/bin/perl + +# +# Convert a ca65 source into HTML +# +# Ullrich von Bassewitz, 05.12.2000 +# + + + +# ---------------------------------------------------------- +# Helper functions +# ---------------------------------------------------------- + + + +# Terminate with an error +sub Abort { + print "@_\n"; + exit 1; +} + +# Print the document header +sub DocHeader { + local $OUT = shift (@_); + local $Asm = shift (@_); + print $OUT <<"EOF"; + + + +SDSL Traffic + + + +


+

$Asm

+


+

+
+EOF
+}
+
+# Print the document footer
+sub DocFooter {
+    local $OUT  = shift (@_);
+    local $Name	= shift (@_);
+
+    # Get the current date and time
+    $Today = localtime;
+
+    print $OUT <<"EOF";
+
+


+


+
+ \"Valid + $Name; generated on $Today by ca65html
+ uz\@cc65.org +
+ + + +EOF +} + + + +# Remove illegal characters from a string +sub Cleanup { + local $S = shift (@_); + $S =~ s/&/&/g; + $S =~ s//>/g; + $S =~ s/\"/"/g; + return $S; +} + + + +# ---------------------------------------------------------- +# Code +# ---------------------------------------------------------- + +# Get the arguments +if ($#ARGV != 1) { + printf STDERR "Usage: %s asm-file output-file\n", $ARGV[0]; + exit (1); +} +$ASM = shift (@ARGV); +$OUT = shift (@ARGV); + +# Open a the input file +open (ASM, "<$ASM") or Abort ("Cannot open $ASM"); + +# Read all lines and remember labels +$LNum = 1; +%Label = (); +while ($Line = ) { + + # Remove the newline + chop ($Line); + + # Check for a label + if ($Line =~ /^\s*([_\w][_\w\d]*)\s*(:|=)/) { + $Label { $1 } = $LNum++; + } elsif ($Line =~ /^\s*(\.import|\.importzp|.proc)\s+(.*?)(\s*)(;.*$|$)/) { + @L = split (/\s*,\s*/, $2); + for my $Id (@L) { + $Label { $Id } = $LNum++; + } + } +} + +# Reset the file pointer to the beginning +seek (ASM, 0, 0); + +# Open the output file and print the HTML header +open (OUT, ">$OUT") or Abort ("Cannot open $OUT"); +DocHeader (OUT, $ASM); + +# The instructions that will have hyperlinks if a label is used +$Ins = "adc|add|and|bcc|bcs|beq|bit|bmi|bne|bpl|bcv|bvs|cmp|cpx|cpy|dec|". + "eor|inc|jmp|jsr|lda|ldx|ldy|ora|rol|sbc|sta|stx|sty|sub|"; + +# Read the input file again, replacing references by hyperlinks and mark +# labels as link targets. +while ($Line = ) { + + # Remove the newline + chop ($Line); + + # Clear the output line + $OutLine = ""; + + # Check for and ignore a local label + if ($Line =~ /^(\s*\@[_\w][_\w\d]*\s*:)(.*)$/) { + # Print the label + $OutLine .= "$1"; + # Use the remainder for line + $Line = $2; + } + + # Check for a label, if we have one, remove it from the line + if ($Line =~ /^\s*([_\w][_\w\d]*)(\s*)(:|=)(.*)$/) { + # Print the label with a tag + $OutLine .= sprintf ("%s%s%s", $Label { $1 }, $1, $2, $3); + # Use the remainder for line + $Line = $4; + } + + # Print any leading whitespace + if ($Line =~ /^(\s+)(.*)$/) { + $OutLine .= "$1"; + $Line = $2; + } + + # Handle the import statements + if ($Line =~ /^(\.import|\.importzp|.proc|)(\s+)(.*)$/) { + $OutLine .= "$1$2"; + $Line = $3; + + # Print all identifiers if there are any + while ($Line =~ /^([_\w][_\w\d]*)(.*)$/) { + $Num = $Label { $1 }; + if ($Num != 0) { + $OutLine .= sprintf ("%s", $Num, $1); + } else { + $OutLine .= "$1"; + } + $Line = $2; + if ($Line =~ /^(\s*),(\s*)(.*)$/) { + $OutLine .= "$1,$2"; + $Line = $3; + } else { + last; + } + } + + # Add an remainder if there is one + $OutLine .= Cleanup ($Line); + + # Check for control commands that may reference lists of labels + } elsif ($Line =~ /^(\.addr|\.word|\.export)(\s+)(.*)$/) { + + # Print the command the and white space + $OutLine .= "$1$2"; + $Line = $3; + + # Print all identifiers if there are any + while ($Line =~ /^([_\w][_\w\d]*)(.*)$/) { + $Num = $Label { $1 }; + if ($Num != 0) { + $OutLine .= sprintf ("%s", $Num, $1); + } else { + $OutLine .= "$1"; + } + $Line = $2; + if ($Line =~ /^(\s*),(\s*)(.*)$/) { + $OutLine .= "$1,$2"; + $Line = $3; + } else { + last; + } + } + + # Add an remainder if there is one + $OutLine .= Cleanup ($Line); + + # Check for any legal instruction + } elsif ($Line =~ /^($Ins)(\s+)(.*)$/) { + + # Print the instruction and white space + $OutLine .= "$1$2"; + $Line = $3; + + # Check for a comment or traling whitespace and separate it + if ($Line =~ /^(.*?)(\s*)(;.*)$/) { + $Line = $1; + $Comment = "$2$3"; + } elsif ($Line =~ /^(.*?)(\s*)$/) { + $Line = $1; + $Comment = $2; + } else { + $Comment = ""; + } + + # Check for the first identifier and replace it by a hyperlink + if ($Line =~ /^([^_a-zA-Z]*)([_a-zA-Z][_\w]*)(.*)$/ && $Label { $2 } != 0) { + $Line = sprintf ("%s%s%s", + Cleanup ($1), $Label { $2 }, $2, Cleanup ($3)); + } + + # Clean the comment + $Comment = Cleanup ($Comment); + + # Reassemble and print the line + $OutLine .= "$Line$Comment"; + + } else { + + # Nothing known - print the line + $OutLine .= Cleanup ($Line); + + } + + # Print the result + print OUT "$OutLine\n"; +} + +# Print the HTML footer +DocFooter (OUT, $OUT); + +# Close the files +close (ASM); +close (OUT); + +# Done +exit 0; +