barrym95838 wrote:
54 bytes of instructions plus a 16-byte table that I zig-zag through several times.
Very well done indeed!
It was immediately apparent that there were four different lines in the object. And each line can be broken down into a series of spaces (possibly none) followed by a star.
At first, I tried to avoid storing duplicates of lines by using a list of line addresses. It turns out that the code to handle those addresses took up more space than the lines saved.
So I ended up using one long string of couplet descriptors.
I also looked at trying to extract some savings from the repetition of a pattern within each line, but could not figure out how to effectively make that work.
The object can be viewed as consisting of a row of diamonds repeated three times. Except that the line of three narrowly separated stars is not repeated between rows of diamonds.
The solution was to omit the top line of stars from the image but emit the bottom line at the beginning for the top line.
Without further ado, this is the first version for the 6800. It has 49 bytes of code and 39 bytes of data.
Code:
00001 * Uncommented, compacted source code submitted for smallest source size
00002
00003 * The object:
00004 *
00005 * * * *
00006 * * * * * * *
00007 * * * * * * *
00008 * * * * *
00009 * * * * * * *
00010 * * * * * * *
00011 * * * *
00012 * * * * * * *
00013 * * * * * * *
00014 * * * * *
00015 * * * * * * *
00016 * * * * * * *
00017 * * * *
00018 * * * * * * *
00019 * * * * * * *
00020 * * * * *
00021 * * * * * * *
00022 * * * * * * *
00023 * * * *
00024 *
00025 *
00026 * The image can be decomposed into four unique types of lines, each
00027 * consisting of several space-star couplets.
00028 *
00029 * A couplet is a number of spaces, 0..5, followed by a star.
00030 *
00031 * -1 spaces denotes the end of the line.
00032 * -2 spaces denotes the end of the image.
00033 *
00034 * The rows of diamonds repeat three times.
00035 *
00036 * Because the line containing the three narrowly spaced stars are not
00037 * repeated between rows of diamonds, a row of diamonds does not include
00038 * the top row; the bottom of the previous row provides those.
00039 *
00040 * That means we must begin by emitting that "bottom" row as the very top row.
00041 *
00042
FFFF 00043 EndOfLine equ -1
FFFE 00044 EndOfImage equ -2
00045
00046 *
00047 * FLEX operating system definitions
00048 *
AD00 00049 OSBase equ $AD00 ; For 6800, $CD00 for 6809
AD03 00050 WARMS equ OSBase+$03 ; Warmstart Entry Point
AD18 00051 PUTCHR equ OSBase+$18 ; Put Character
AD24 00052 PCRLF equ OSBase+$24 ; Print Carriage Return and Line Feed
00053
0000 04 00054 Count fcb 4 ; Repeat three times plus top row
00055
0001 00056 Image
0001 02 01 03 01 00057 fcb 2,1,3,1,3,1,EndOfLine
0005 03 01 FF
0008 01 03 01 03 00058 fcb 1,3,1,3,1,3,EndOfLine
000C 01 03 FF
000F 00 05 05 05 00059 fcb 0,5,5,5,EndOfLine
0013 FF
0014 01 03 01 03 00060 fcb 1,3,1,3,1,3,EndOfLine
0018 01 03 FF
001B 02 01 03 01 00061 fcb 2,1,3,1,3,1,EndOfLine
001F 03 01 FF
00062
0022 00063 Top
0022 03 05 05 FF 00064 fcb 3,5,5,EndOfLine
00065
0026 FE 00066 fcb EndOfImage
00067
0027 00068 Start
0027 BD AD24 [9] 00069 jsr PCRLF ; FLEX does not do CRLF from prompt
00070
002A CE 0021 [3] 00071 ldx #Top-1 ; Point to before top row
00072
002D 20 03 (0032) [4] 00073 bra LineLoop
00074
002F 00075 ImageLoop
002F CE 0000 [3] 00076 ldx #Image-1 ; Point to before start of the image
00077
0032 00078 LineLoop
0032 08 [4] 00079 inx ; Point to the next couplet
0033 E6 00 [5] 00080 ldab 0,X ; Get the couplet
0035 2B 11 (0048) [4] 00081 bmi Special
00082
0037 27 08 (0041) [4] 00083 beq NoSpaces
00084
0039 86 20 [2] 00085 ldaa #' ' ; Emit spaces
00086
003B 00087 SpaceLoop
003B BD AD18 [9] 00088 jsr PUTCHR
00089
003E 5A [2] 00090 decb
003F 26 FA (003B) [4] 00091 bne SpaceLoop
00092
0041 00093 NoSpaces
0041 86 2A [2] 00094 ldaa #'*' ; Emit star
00095
0043 BD AD18 [9] 00096 jsr PUTCHR
00097
0046 20 EA (0032) [4] 00098 bra LineLoop
00099
0048 00100 Special
0048 5C [2] 00101 incb
0049 26 05 (0050) [4] 00102 bne EndImage
00103
004B BD AD24 [9] 00104 jsr PCRLF ; Start a new line
00105
004E 20 E2 (0032) [4] 00106 bra LineLoop
00107
0050 00108 EndImage
0050 7A 0000 [6] 00109 dec Count ; Do it again?
0053 26 DA (002F) [4] 00110 bne ImageLoop
00111
0055 7E AD03 [3] 00112 jmp WARMS ; Back to FLEX
00113
0027 00114 end Start
Then comes the version for the 6809. It has 47 bytes of code and 39 bytes of data.
Code:
FFFF 00043 EndOfLine equ -1
FFFE 00044 EndOfImage equ -2
00045
00046 *
00047 * FLEX operating system definitions
00048 *
CD00 00049 OSBase equ $CD00 ; For 6809, $AD00 for 6800
CD03 00050 WARMS equ OSBase+$03 ; Warmstart Entry Point
CD18 00051 PUTCHR equ OSBase+$18 ; Put Character
CD24 00052 PCRLF equ OSBase+$24 ; Print Carriage Return and Line Feed
00053
0000 04 00054 Count fcb 4 ; Repeat three times plus top row
00055
0001 00056 Image
0001 02 01 03 01 00057 fcb 2,1,3,1,3,1,EndOfLine
0005 03 01 FF
0008 01 03 01 03 00058 fcb 1,3,1,3,1,3,EndOfLine
000C 01 03 FF
000F 00 05 05 05 00059 fcb 0,5,5,5,EndOfLine
0013 FF
0014 01 03 01 03 00060 fcb 1,3,1,3,1,3,EndOfLine
0018 01 03 FF
001B 02 01 03 01 00061 fcb 2,1,3,1,3,1,EndOfLine
001F 03 01 FF
00062
0022 00063 Top
0022 03 05 05 FF 00064 fcb 3,5,5,EndOfLine
00065
0026 FE 00066 fcb EndOfImage
00067
0027 00068 Start
0027 BD CD24 [8] 00069 jsr PCRLF ; FLEX does not do CRLF from prompt
00070
002A 8E 0022 [3] 00071 ldx #Top ; Point to top row
00072
002D 20 03 (0032) [3] 00073 bra LineLoop
00074
002F 00075 ImageLoop
002F 8E 0001 [3] 00076 ldx #Image ; Point to start of the image
00077
0032 00078 LineLoop
0032 E6 80 [6] 00079 ldb ,X+ ; Get the couplet
0034 2B 11 (0047) [3] 00080 bmi Special
00081
0036 27 08 (0040) [3] 00082 beq NoSpaces
00083
0038 86 20 [2] 00084 lda #' ' ; Emit spaces
00085
003A 00086 SpaceLoop
003A BD CD18 [8] 00087 jsr PUTCHR
00088
003D 5A [2] 00089 decb
003E 26 FA (003A) [3] 00090 bne SpaceLoop
00091
0040 00092 NoSpaces
0040 86 2A [2] 00093 lda #'*' ; Emit star
00094
0042 BD CD18 [8] 00095 jsr PUTCHR
00096
0045 20 EB (0032) [3] 00097 bra LineLoop
00098
0047 00099 Special
0047 5C [2] 00100 incb
0048 26 05 (004F) [3] 00101 bne EndImage
00102
004A BD CD24 [8] 00103 jsr PCRLF ; Start a new line
00104
004D 20 E3 (0032) [3] 00105 bra LineLoop
00106
004F 00107 EndImage
004F 0A 00 [6] 00108 dec Count ; Do it again?
0051 26 DC (002F) [3] 00109 bne ImageLoop
00110
0053 7E CD03 [4] 00111 jmp WARMS ; Back to FLEX
00112
0027 00113 end Start
The 6502 version initially looked very promising in the beginning as I was pursuing the table of line addresses as those addresses are a single byte in the zero page. That advantage evaporated when going with a single long line. It has 48 bytes of code and 39 bytes of data. If my cross assembler and emulator supported the CMOS instructions, namely the relative absolute branch, the 6502 would have won by one byte.
Code:
00FF 00043 EndLine equ $FF
00FE 00044 EndOfImage equ $FE
00045
00046 *
00047 * FLEX operating system definitions
00048 *
1000 00049 DOSBase equ $1000
1003 00050 WARMS equ DOSBase+$03 ; Warmstart Entry Point
1018 00051 PUTCHR equ DOSBase+$18 ; Put Character
1024 00052 PCRLF equ DOSBase+$24 ; Print Carriage Return and Line Feed
00053
0000 04 00054 Count fcb 4 ; Repeat three times plus top row
00055
0001 00056 Image:
0001 02 01 03 01 03 01 00057 fcb 2,1,3,1,3,1,EndLine
0007 FF
0008 01 03 01 03 01 03 00058 fcb 1,3,1,3,1,3,EndLine
000E FF
000F 00 05 05 05 FF 00059 fcb 0,5,5,5,EndLine
0014 01 03 01 03 01 03 00060 fcb 1,3,1,3,1,3,EndLine
001A FF
001B 02 01 03 01 03 01 00061 fcb 2,1,3,1,3,1,EndLine
0021 FF
00062
0022 00063 Top:
0022 03 05 05 FF 00064 fcb 3,5,5,EndLine
0026 FE 00065 fcb EndOfImage
00066
0027 00067 Start:
0027 20 1024 [6] 00068 jsr PCRLF ; FLEX does not do CRLF from prompt
00069
002A A2 21 [2] 00070 ldx #Top-1 ; Point to before the top row
00071
002C D0 02 (0030) [2/3] 00072 bne LineLoop ; Always branches
00073
002E 00074 ImageLoop:
002E A2 00 [2] 00075 ldx #Image-1 ; Point to before the image
00076
0030 00077 LineLoop:
0030 E8 [2] 00078 inx ; Point to the next couplet
0031 B4 00 [4] 00079 ldy 0,X ; Get the couplet
0033 30 12 (0047) [2/3] 00080 bmi Special
00081
0035 F0 08 (003F) [2/3] 00082 beq NoSpaces
00083
0037 A9 20 [2] 00084 lda #' ' ; Emit spaces
00085
0039 00086 SpaceLoop:
0039 20 1018 [6] 00087 jsr PUTCHR
00088
003C 88 [2] 00089 dey
003D D0 FA (0039) [2/3] 00090 bne SpaceLoop
00091
003F 00092 NoSpaces:
003F A9 2A [2] 00093 lda #'*' ; Emit star
00094
0041 20 1018 [6] 00095 jsr PUTCHR
00096
0044 4C 0030 [3] 00097 jmp LineLoop
00098
0047 00099 Special:
0047 C8 [2] 00100 iny
0048 D0 06 (0050) [2/3] 00101 bne EndImage
00102
004A 20 1024 [6] 00103 jsr PCRLF ; Start a new line
00104
004D 4C 0030 [3] 00105 jmp LineLoop
00106
0050 00107 EndImage:
0050 C6 00 [5] 00108 dec Count ; Do it again?
0052 D0 DA (002E) [2/3] 00109 bne ImageLoop
00110
0054 4C 1003 [3] 00111 jmp WARMS ; Back to FLEX
00112
0027 00113 end Start
Because it was so different, I did not write the version for the 8080 until the others were done. It has 76 bytes of code and 38 bytes of data as I kept the count in a register. Note that the interface to CP/M cost additional instructions to preserve register contents.
Code:
00FF 00043 EndLine equ 0FFh
00FE 00044 EndOfImage equ 0FEh
00045
0005 00046 BDOS equ 5
00047
0100 00048 org 100h
00049
0100 00050 Start:
0100 0E 04 [7] 00051 mvi C,4 ; Repeat three times plus the top row
00052
0102 21 016D [10] 00053 lxi H,Top ; Point to the top line
00054
0105 C3 010B [10] 00055 jmp LineLoop
00056
0108 00057 ImageLoop:
0108 21 014C [10] 00058 lxi H,Image ; Point to the image
00059
010B 00060 LineLoop:
010B 46 [7] 00061 mov B,M ; Get the couplet
010C 23 [5] 00062 inx H ; Point to the next couplet
010D 78 [5] 00063 mov A,B
010E B7 [4] 00064 ora A
010F FA 0126 [10] 00065 jm Special
00066
0112 CA 011E [10] 00067 jz NoSpaces
00068
0115 1E 20 [7] 00069 mvi E,' ' ; Emit spaces
00070
0117 00071 SpaceLoop:
0117 CD 0140 [17] 00072 call PUTCHR
00073
011A 05 [5] 00074 dcr B
011B C2 0117 [10] 00075 jnz SpaceLoop
00076
011E 00077 NoSpaces:
011E 1E 2A [7] 00078 mvi E,'*' ; Emit star
00079
0120 CD 0140 [17] 00080 call PUTCHR
00081
0123 C3 010B [10] 00082 jmp LineLoop
00083
0126 00084 Special:
0126 3C [5] 00085 inr A
0127 C2 0130 [10] 00086 jnz EndImage
00087
012A CD 0139 [17] 00088 call PCRLF ; Start a new line
00089
012D C3 010B [10] 00090 jmp LineLoop
00091
0130 00092 EndImage:
0130 0D [5] 00093 dcr C ; Do it again?
0131 C2 0108 [10] 00094 jnz ImageLoop
00095
0134 0E 00 [7] 00096 mvi C,0 ; Back to CP/M
0136 C3 0005 [10] 00097 jmp BDOS
00098
0139 00099 PCRLF:
0139 1E 0D [7] 00100 mvi E,0Dh ; Print CR
013B CD 0140 [17] 00101 call PUTCHR
00102
013E 1E 0A [7] 00103 mvi E,0Ah ; Now LF
00104
0140 00105 PUTCHR:
0140 F5 [11] 00106 push PSW
0141 C5 [11] 00107 push B
0142 E5 [11] 00108 push H
00109
0143 0E 02 [7] 00110 mvi C,2
0145 CD 0005 [17] 00111 call BDOS
00112
0148 E1 [10] 00113 pop H
0149 C1 [10] 00114 pop B
014A F1 [10] 00115 pop PSW
00116
014B C9 [10] 00117 ret
00118
014C 00119 Image:
014C 02 01 03 01 03 01 00120 db 2,1,3,1,3,1,EndLine
0152 FF
0153 01 03 01 03 01 03 00121 db 1,3,1,3,1,3,EndLine
0159 FF
015A 00 05 05 05 FF 00122 db 0,5,5,5,EndLine
015F 01 03 01 03 01 03 00123 db 1,3,1,3,1,3,EndLine
0165 FF
0166 02 01 03 01 03 01 00124 db 2,1,3,1,3,1,EndLine
016C FF
00125
016D 00126 Top:
016D 03 05 05 FF 00127 db 3,5,5,EndLine
00128
0171 FE 00129 db EndOfImage
This is the file ID from my submission:
Quote:
VCCC2023 in 6809 Assembly Language for FLEX
Author: Bill Gee
Category: Christmas Challenge
System: 6809 Computer (SWTPC compatible) running FLEX
Language: Assembly language
Len source code: 290 bytes
Len exe file: 93 bytes
Len code only: 47 bytes of executable code, 39 bytes of data
Instructions:
Download and install ReFLEX
http://datapipe-blackbeltsystems.com/wi ... tml#reflexOpen VCCC2023.DSK as diskette #2
"2.VCCC2023" to run.
If you want to assemble the source:
ASN W=2
ASMB VCCC2023
RENAME VCCC2023.BIN VCCC2023.CMD
Description:
The image can be decomposed into four unique types of lines, each
consisting of several space-star couplets.
A couplet is a number of spaces, 0..5, followed by a star.
-1 spaces denotes the end of the line.
-2 spaces denotes the end of the image.
The rows of diamonds repeat three times.
Because the line containing the three narrowly spaced stars are not
repeated between rows of diamonds, a row of diamonds does not include
the top row; the bottom of the previous row provides those.
That means we must begin by emitting that "bottom" row as the very top row.
Comments:
ZIP file contents:
FILE_ID.DIZ - This file
REFLEX.PNG - Screen shot of program run in ReFLEX emulator
VCCC2023.TXT - Source code in FLEX format
VCCC2023.CMD - Assembled executable
VCCC2023.DSK - Virtual disk for use with ReFLEX
VC9-2023.LST - Assembly listing of commented and uncompacted source code
Oh yeah, Merry Christmas!
and the compacted source code:
Code:
E fcb 4
F fcb 2,1,3,1,3,1,-1,1,3,1,3,1,3,-1,0,5,5,5,-1,1,3,1,3,1,3,-1,2,1,3,1,3,1,-1
G fcb 3,5,5,-1,-2
H jsr $CD24
ldx #G
bra J
I ldx #F
J ldb ,X+
bmi M
beq L
lda #32
K jsr $CD18
decb
bne K
L lda #'*
jsr $CD18
bra J
M incb
bne N
jsr $CD24
bra J
N dec E
bne I
jmp $CD03
end H