📄 exa6.html
字号:
<!doctype html public "-//W3C//DTD HTML 3.2//EN"><html><head><title>Example 6: fixpiccy</title><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" /><meta http-equiv="content-language" content="en" /><meta name="resource-type" content="document"><meta name="copyright" content="This document copyright 2001 by Richard Murray. Use for non-profit and education purposes explicitly granted."><meta name="author" content="Richard Murray"><meta name="rating" content="general"></head><!-- /assembler/exa6.html --><!-- --><!-- (C) Copyright 2000 Richard Murray --><!-- Designed by Richard Murray --><!-- rmurray@heyrick.co.uk --><!-- --><body bgcolor="#f0f0f0" text="#000000" link="#0022dd" vlink="#002288"><table border = "0" width="100%"> <tr> <td align=center width=100> <img src="arm3.gif" width=79 height=78 align = middle> </td> <td> <h1 align="center"><font color="#800080">Example 6<br>fixpiccy</font></h1> </td> <td align=center width=100> <img src="arm3.gif" width=79 height=78 align = middle> </td></table><p> <p> <p><h2>Introduction:</h2>I used my Vision digitiser to grab frames from EuroSport's coverage of the Tour de France. Allwent well, except that the saved frames are MODE 21 sprites. When viewed full-screen (via theScreenLoad command), they were rather flickery on my monitor.<br>The pixel depth of MODE 28 is the same as MODE 21, though the screen dimensions are slightlysmaller - 640 x 480 as opposed to 640 x 512. A side effect of this, however, is the refresh rateis higher, leading to a sharper unflickering display.<p>Thus, <i>fixpiccy</i> was devised. It simply whips through the given directory structureexamining sprite files. When it finds one, it looks to see if it is a MODE 21 sprite...if so, itwill be converted using what I like to call <i>the sledgehammer method</i> - ie, the mode byteis simply changed. No fancy stuff.<p>If no path is given, it will work out which directory it is currently in, and scan that. So ifyou had a directory full of pictures that you were constantly adding to (as I was), then you canplace <i>fixpiccy</i> into that directory, and just double-click on the program to get going.No need for Obey files or the like.<p><i>fixpiccy</i> takes between zero and two parameters. If none are given, it will scan thedirectory that it is within (not the CSD). The other two parameters are"<code>-quiet</code>" (to inhibit any status output), and the directory path. Eitheror both can exist, in any order. No other parameters are valid. The first thing found that isnot '-quiet' will be assumed to be a path.<p><b><u>IMPORTANT:</u></b> <i>fixpiccy</i> is designed to work with single-sprite sprite files. Ihave not tested behaviour with multiple-sprite files. Support for those, if required, is left asan exercise for the budding assembly language coder (that's <b>you</b>!).<p>The program is in two sections. The first, <code>c.main</code> is the wrapper. It gets the wholething going, sorts out the command line parameters, and scans the directories. The second part,<code>s.picfixer</code> is the assembler code that handles the sprite interrogation/fixing.<br>Typically one would code a large application in a high level language such as C, then useassembler for the speed critical parts. Pretty much the way you might code processor intensivecode in BASIC.<br>Note, that this example is simply that. An example.<br>There is little speed benefit to have been gained in writing the image scanner in assembler.Indeed, the compiler might have been able to generate better code than I for this function.<p> <p> <p><h2>The C code:</h2>The code is fairly self explanatory. If you do not have a C compiler, it is available in theexample archive as <code>o.main</code>. Though, by now you might like to have a crack at writinga simple assembler wrapper for it yourself.<p>As you can see, an assembler function is simply defined as an <code>extern</code> function, likefunctions in other source modules. You define the parameters of the function, and when called,the first parameter is in R0, the next in R1, etc.<p>This version of the software has several of the comments removed, to save space here. The copy inthe archive is complete.<br>Additionally, the text size has been reduced slightly.<br>The important lines, to do with calling the assembler function, are highlighted in blue.<pre><font size = -1>/* fixpiccy Name : fixpiccy Version: v0.01 Date : Saturday, 15th July 2000 Project begun 15th July 2000 Purpose: Library utility to 'fix' MODE 21 pictures to be MODE 28. Creator: Richard Murray *** Downloaded from http://www.heyrick.co.uk/assembler/ ****/#include <ctype.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <signal.h>#include "kernel.h"#include "swis.h"#define TRUE 1#define FALSE 0static _kernel_swi_regs r;static struct catdat /* OS_GBPB 12 catalogue data */{ int load_address; int exec_address; int length; int file_attributes; int object_type; int object_file_type; char object_name[40]; /* = 64 bytes, only 11 wanted for object_name[] */}; /* (mmm, what's the API for RO4 long filenames?) */static struct catdat *catdata = NULL;static char scan_dir[256] = "";static int quiet = FALSE;static void scan_directory(char *);static void escape_key(int);</font><font size = -1 color=blue>extern void fix_picture(char *, int);</font><font size = -1>int main(int argc, char *argv[]){ int loop = 0; signal(SIGINT, escape_key); catdata = calloc(1, sizeof(struct catdat)); if (!catdata) { fprintf(stderr, "Unable to allocate space for file descriptor (need 64 bytes)\n"); exit(EXIT_FAILURE); } if (argc > 1) { for (loop = 1; loop < argc; loop++) if (strcmp(argv[loop], "-quiet") == NULL) /* If parameter is "-quiet", do so */ quiet = TRUE; else strcpy(scan_dir, argv[loop]); /* Else assume parameter is a path */ } if (strlen(scan_dir) == 0) { /* No path? Calculate our own. */ strcpy(scan_dir, argv[0]); loop = strlen(scan_dir); while ( (scan_dir[loop] != '.') && (loop > 0) ) loop--; scan_dir[loop] = '\0'; } if (!quiet) { printf("fixpiccy v0.01 %c 2000 Richard Murray\n==============\n\n", 169); printf("Starting search in \"%s\"\n\n", scan_dir); } scan_directory(scan_dir); exit(EXIT_SUCCESS);}static void scan_directory(char *path){ /* Search for sprites to process */ int scan_next = 0; char scan_obj[256]; do { /* OS_GBPB 12 - see PRM p2-70 and 2-71 */ r.r[0] = 12; r.r[1] = (int) path; r.r[2] = (int) catdata; r.r[3] = 1; r.r[4] = scan_next; r.r[5] = 64; r.r[6] = (int) "*"; _kernel_swi(OS_GBPB, &r, &r); scan_next = r.r[4]; if (scan_next != -1 && scan_next != 0) { if (catdata->object_type != 0) { sprintf(scan_obj, "%s.%s", path, catdata->object_name); if (catdata->object_file_type == 0xFF9) { /* It is a sprite */ if (!quiet) printf("Sprite : \"%s\"\n", catdata->object_name); </font><font size = -1 color=blue>fix_picture(scan_obj, quiet);</font><font size = -1> } else { if (catdata->object_file_type == 0x1000) { /* It is a directory */ if (!quiet) printf("\nScanning directory \"%s\"\n\n", catdata->object_name); scan_directory(scan_obj); } } } } } while (scan_next > 0); if (!quiet) printf("\n"); return;}static void escape_key(int sig){ sig = sig; printf("\nEscape (exiting)\n\n"); exit(EXIT_FAILURE);}</font></pre>See? Just like calling a C function!<p> <p> <p><h2>The assembler code:</h2>This is the real stuff. Proper, interwoven in high level language environment assembler. Asmentioned above, don't go recoding all sorts of things in assembler just for the sake of it.Unless you want the exercise, there isn't much point. This is, purely, for the exercise.<grin><p>You'll see there is no entry directive. The C compiler has this set for the<code>main()</code> procedure. Instead, we set up our code to reside in the area called<code>C$$code</code> (also defined by the C compiler).<br>In order to make our code accessible, we must export it so that it may be known to the linker.This is achieved with the use of the <code>EXPORT</code> directive. There is no need to specifythe input/output parameters. That is done in the high level language by means of the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -