⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exa3.html

📁 关于ARM汇编的非常好的教程
💻 HTML
字号:
<!doctype html public "-//W3C//DTD HTML 3.2//EN"><html><head><title>Example 3: Better compression and multi-format loader</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/exa3.html               --><!--                                     --><!--  (C) Copyright 1999 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 3<br>Better compressor<br>and<br>      multi-format loader</font></h1>    </td>    <td align=center width=100>      <img src="arm3.gif" width=79 height=78 align = middle>    </td>  </tr></table><p>&nbsp;<p>In the last part I said, &quot;So we shall, in the next part, propose a new format that willmake the compression even more efficient.&quot;<p>So, then, how can we make the compression more efficient? Remember that our compression was goodon solid areas of colour but a bit rubbish when it came down to dithered or complicated images.Consider:<p><pre>  HEADER:  (26 bytes)-&quot;BudgieScrn (compressed 2)&quot;           &lt;cr&gt;  MODE:    (1 byte)-Screen mode.  PALETTE: (16 * 6 bytes)-Bytes giving R, G & B components of           first flash colour.           Bytes giving R, G, & B components of second flash           colour.  IMAGE DATA:           If byte = 255, then loop data follows. Next byte           is the colour. Third byte is a count (0 - 254)           of how many pixels of this colour to fill in.           If byte &lt;&gt; 255, then byte is regular screen           memory. Just stick it straight to the screen...</pre>Immediately, two things should be noticed:<ol>  <li> If the legitimate pair is colour 15, then the byte will be 255 causing a loop. Thus, in a       sequence of aligned doubles of colour 15 with something in between, it could begin to get       wasteful. However such a sequence seems unlikely. If the colour 15 double extends for       further pixels, a loop <i>would</i> be required.  <li> This will better cope with dithered images, as two pixels will therefore take one byte       instead of four (previously, loop count and colour for each pixel).</ol>It sounds horribly complex doesn't it? However in reality all we need is a look-ahead andsomething to fiddle occurances of colour 15 doubles. For a change, we shall present the savecode in BASIC because it is easier to follow (and additionally I have not coded an assemblerversion yet! :-) ). As usual, the loader is more or less a reverse of the saver, and that is inassembler.<p>The program is commented, so shouldn't need any further explanation. Converting it to assembleris left as an exercise for the reader.<p><pre>REM &gt;Ssaver2REM Compress sprites using BudgieSoft compression algorithmREM (type 2).REMREM by Richard Murray Winter 1997REMREM Downloaded from: http://www.heyrick.co.uk/assembler/:ON ERROR PRINT REPORT$+&quot; at &quot;+STR$(ERL/10) : END:REM Open output file (put your own path here, or read fromREM command line).x%=OPENOUT(&quot;IDEFS::Willow.$.WWW.WWWsite.assembler.sw.screen2/raw&quot;):REM Write out the identification header...BPUT#x%, &quot;BudgieScrn (compressed 2)&quot;:REM ...and the current screenmode.BPUT#x%, MODE:REM Build up palette entries, and write out.FOR loop% = 0 TO 15  SYS &quot;OS_ReadPalette&quot;, loop%, 16 TO ,,f%, s%  r1% = (f% &gt;&gt; 8) AND 255      : REM First flash colour                                 REM red component  g1% = (f% &gt;&gt; 16) AND 255     : REM First flash colour                                 REM green component  b1% = (f% &gt;&gt; 24) AND 255     : REM First flash colour                                 REM blue component  r2% = (s% &gt;&gt; 8) AND 255      : REM Second flash colour                                 REM red component  g2% = (s% &gt;&gt; 16) AND 255     : REM Second flash colour                                 REM green component  b2% = (s% &gt;&gt; 24) AND 255     : REM Second flash colour                                 REM blue component  BPUT#x%, r1% : BPUT#x%, g1% : BPUT#x%, b1%  BPUT#x%, r2% : BPUT#x%, g2% : BPUT#x%, b2%NEXT:REM Get our screen sizes. This is not written to file. TheREM loader will have to figure out it's own screen dimensions.REM Then switch off the cursor.DIM b% 19b%!0=149 : b%!4=7 : b%!8=-1SYS &quot;OS_ReadVduVariables&quot;, b%, b%+12base%=b%!12 : length%=b%!16 :end%=base%+length%SYS &quot;XOS_RemoveCursors&quot;::REM Now read from base% to end% (via posn%) calculating theREM data, writing it out to file as necessary.:posn% = base%REPEAT  REM Read four pixels (two bytes) at a time.  REM If they match, begin a loop.  col1% = posn%?0  col2% = posn%?1  IF col1% = col2% THEN    REM They match, so...    BPUT#x%, 255    BPUT#x%, col1%    counter% = 0    REPEAT      col1% = posn%?0      IF col1% = col2% THEN        counter%+=1        posn%+=1      ENDIF    UNTIL counter% = 255 OR (col1% &lt;&gt; col2%)    BPUT#x%, counter%  ELSE    REM Otherwise write out pixels.    BPUT#x%, col1%    IF col1% = 255 THEN      REM A little hack for colour 15 double (byte = 255).      BPUT#x%, col1%      BPUT#x%, 0    ENDIF    posn% += 1  ENDIF  REM Until end.UNTIL posn% &gt;=end%:REM Close file and exit.CLOSE#x%END</pre>Apart from a few little changes in the loader routine, it is very similar to the existing loader.The differences, mainly, are:<pre>  .main_loop    Read a byte.    Is it '255'?      If so, branch with link to read_loop.      Write byte (pixel pair) to screen.    Look to see if we are at the end of screen.      If not, branch to main_loop.    Close and exit etc etc.  .read_loop    Read colour byte.    Read length byte.  .loop2    Subtract 1 from length.    Write colour byte to screen.    Length is zero?      If not, branch to loop2.    End of screen?      If not, branch to main_loop.    Otherwise exit.</pre>I'll leave you to compare the above flow with the program itself. It is commented so youshouldn't have too many problems.<p><div align = right><a href="sw/ssaver2.basic"><i>Download example: ssaver2.basic</i></a></div><p>&nbsp;<p>&nbsp;<p>To current date there is no type 2 saver in assembler. I use the BASIC code mentioned previously.So instead I will treat you to a loader that handles <i>all three</i> versions.<p>The code is commented, but it is not split into annotated chunks as before. You should be able tofollow what is going on.<pre>REM &gt;Sloader2 BudgieSoft screen loader (all versions)REM Version 0.21REMREM by Richard Murray Winter 1997REMREM Downloaded from: http://www.heyrick.co.uk/assembler/:ON ERROR PRINT REPORT$+&quot; at &quot;+STR$(ERL/10) : END:PROCassembleOSCLI(&quot;Save &lt;Obey$Dir&gt;.Loader &quot;+STR$~(code%)+&quot; &quot;+STR$~(O%))OSCLI(&quot;SetType &lt;Obey$Dir&gt;.Loader &amp;FFC&quot;)END:DEFPROCassemble  DIM code% &amp;1000  FOR pass% = 4 TO 6 STEP 2    P%=0    O%=code%    [ OPT pass%      MOV    R10, R14      MOV    R0, #&amp;4C      SWI    &quot;XOS_Find&quot;      BVS    exit      MOV    R5, R0      ; Skip header      MOV    R8, #0    .skip_header      MOV    R1, R5      BL     read_byte      ADD    R8, R8, #1      CMP    R8, #23      BLT    skip_header      MOV    R1, R5      BL     read_byte      CMP    R0, #10      ; Newline - version 0.      BEQ    version_zero      CMP    R0, #49      ; '1' - version 1.      BEQ    version_one      CMP    R0, #50      ; '2' - version 2.      BEQ    version_two      ADR    R0, unknown_string      SWI    &quot;OS_PrettyPrint&quot;      SWI    &quot;OS_NewLine&quot;      SWI    &quot;OS_NewLine&quot;      B      exit    .unknown_string      EQUS   &quot;Unable to load this screen - the format&quot;      EQUS   &quot; has not been recognised...&quot;      EQUB   0      ALIGN    ; *** VERSION ZERO HANDLER ***    .version_zero      B      load_old_format    ; *** VERSION ONE HANDLER ***    .version_one      MOV    R1, R5      BL     read_byte      BL     read_byte      B      load_old_format    ; *** VERSION TWO HANDLER    .version_two      MOV    R1, R5      BL     read_byte      BL     read_byte      B      load_new_format    ; *** OLD FORMAT LOADER ***    .load_old_format      BL     switch_screen_mode      BL     get_screen_info      BL     load_palette    .old_loop      MOV    R1, R5      BL     read_byte      MOV    R4, R0      BL     read_byte    .old_loop2      SUB    R0, R0, #1      STRB   R4, [R2, #1]!      CMP    R0, #0      BGT    old_loop2      CMP    R2, R3      BLT    old_loop      B      exit    ; *** NEW FORMAT LOADER ***    .load_new_format      BL     switch_screen_mode      BL     get_screen_info      BL     load_palette    .new_loop      MOV    R1, R5      BL     read_byte      CMP    R0, #255      BLEQ   read_loop      STRB   R0, [R2, #1]!      CMP    R2, R3      BLT    new_loop      B      exit    ; *** RESOURCES ***    .switch_screen_mode      MOV    R12, R14      MOV    R0, #&amp;87      SWI    &quot;XOS_Byte&quot;      MOV    R1, R5      BL     read_byte      CMP    R0, R2      SWINE  &amp;100 + 22      SWINE  &quot;OS_WriteC&quot;      MOV    PC, R12    .get_screen_info      ADR    R0, vdu_block      ADD    R1, R0, #12      SWI    &quot;OS_ReadVduVariables&quot;      LDR    R2, [R1]      LDR    R3, [R1, #4]      ADD    R3, R3, R2      SUB    R2, R2, #1      MOV    PC, R14    .load_palette      MOV    R12, R14      MOV    R4, #0      ADR    R7, os_block    .col_loop      MOV    R1, R5      STRB   R4, [R7, #0]      MOV    R0, #17      STRB   R0, [R7, #1]      BL     read_byte      STRB   R0, [R7, #2]      BL     read_byte      STRB   R0, [R7, #3]      BL     read_byte      STRB   R0, [R7, #4]      MOV    R0, #&amp;0C      MOV    R1, R7      SWI    &quot;OS_Word&quot;      MOV    R1, R5      MOV    R0, #18      STRB   R0, [R7, #1]      BL     read_byte      STRB   R0, [R7, #2]      BL     read_byte      STRB   R0, [R7, #3]      BL     read_byte      STRB   R0, [R7, #4]      MOV    R0, #&amp;0C      MOV    R1, R7      SWI    &quot;OS_Word&quot;      ADD    R4, R4, #1      CMP    R4, #16      BLT    col_loop      MOV    R0, #0      MOV    PC, R12    .exit      MOV    R2, R0      MOV    R1, R5      MOV    R0, #0      SWI    &quot;XOS_Find&quot;      MOV    PC, R10    .read_byte      SWI    &quot;XOS_BGet&quot;      MOVVC  PC, R14    .read_loop                ; Read and deal with loop data.      MOV     R1, R5      BL      read_byte       ; Read colour      MOV     R4, R0      BL      read_byte       ; Read length    .loop2      SUB     R0, R0, #1      STRB    R4, [R2, #1]!      CMP     R0, #0          ; More to loop?      BGT     loop2      CMP     R2, R3          ; End of screen?      BLT     new_loop      B       exit    .vdu_block      EQUD   149      EQUD   7      EQUD   -1      EQUD   0      EQUD   0    .os_block      EQUD   0      EQUB   0      ALIGN    ]  NEXTENDPROC</pre>This concludes our series on creating compressed screen software. If you wish to write anassembler saver for type 2 files, please do so. Likewise, bug reports and such would also bewelcomed.<p><div align = right><a href="sw/sloader2.basic"><i>Download example: sloader2.basic</i></a></div><div align = right><a href="sw/screen2.raw"><i>Download example compressed screen (type 2):screen2.raw</i></a></div><p>&nbsp;<p>&nbsp;<p>By way of comparison, here is a type 1 version of the above image. It is a moderately balancedimage, a textured JPEG and textured windows alongside plain windows.<p><div align = right><a href="sw/compscrn.raw"><i>Download example compressed screen:compscrn.raw</i></a></div><p>The type 1 screen is 159771 bytes.<br>The type 2 screen is 123369 bytes.<p><hr size = "3"><a href="index.html#15">Return to assembler index</a><hr size = "3"><address>Copyright &copy; 1999 Richard Murray</address></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -