6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Apr 27, 2024 11:07 am

All times are UTC




Post new topic Reply to topic  [ 48 posts ]  Go to page Previous  1, 2, 3, 4  Next
Author Message
PostPosted: Thu Dec 21, 2023 2:51 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1926
Location: Sacramento, CA, USA
TMI, Rob! Please delete your code before someone chews you out!

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
PostPosted: Thu Dec 21, 2023 2:59 am 
Offline

Joined: Sun Apr 26, 2020 3:08 am
Posts: 357
barrym95838 wrote:
My VTL-2 version is disappointing in a head-to-head comparison with 6502 machine language, at least when using the same algorithm. Kinda makes sense, though ... LDA #50 is two bytes and two CPU cycles, and 100 A=50 is eight bytes and (mumble) CPU cycles. I am also not pleased with the portability issue associated with my rendering technique ... it uses spaces instead of newline chars, which isn't bad for the original WOZMON, but horrible on a generic terminal connected to a typical VTL-2 host, because not many of those terminals wrap lines at 40 columns like the Apple 1 does.


Well, that's not good. I was hoping your tiny language could also make tiny programs! I was hoping to play with it some more.


Top
 Profile  
Reply with quote  
PostPosted: Mon Dec 25, 2023 12:10 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 690
Location: North Tejas
Please motivate me.

I have written programs for the 6800, 6809, 6502 and 8080.

The 6502 one is one byte smaller than the 6800 one. The 6809 one managed to shave two bytes from the 6800 one, making it one byte smaller than the 6502. The 8080 one is somewhat larger than the others.

Now I face the task of preparing the package to enter the contest and I am not feeling like doing that work.

As stated before, the rules state

Quote:
Can I use the stub of an assembler program to store data or use side effects of the stub like zero-page or registers variables (e.g. basic line number) set by the stub?

No, you can't. If you do so, you also can't subtract the size of the stub (from the executed code) as a consequence. Exception: start address. Every program needs to start. So, if the starting process sets a register or zero-page address, you can use this side effect.


But the winner from last year does appear to be setting a bunch of stuff in the stub whose size is not counted.

Whether I enter or not, I will be posting my code come Boxing Day...


Top
 Profile  
Reply with quote  
PostPosted: Mon Dec 25, 2023 8:58 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10793
Location: England
I too felt that the submission process was overly difficult. So I decided that I might or might not try the challenge in future, but wouldn't submit.

Another approach is to submit using only the amount of effort you want to - be lax, be brief, ignore any requirement which is too difficult or doesn't seem meaningful. At worst your entry will not qualify. Possibly you'll get an email requesting necessary extras.


Top
 Profile  
Reply with quote  
PostPosted: Mon Dec 25, 2023 10:16 am 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1398
Location: Scotland
BigEd wrote:
I too felt that the submission process was overly difficult. So I decided that I might or might not try the challenge in future, but wouldn't submit.

Another approach is to submit using only the amount of effort you want to - be lax, be brief, ignore any requirement which is too difficult or doesn't seem meaningful. At worst your entry will not qualify. Possibly you'll get an email requesting necessary extras.


I think there is some sort of balance - but the question is where/what and if I were the one posing, sorting and presenting the entries I'd want to make it as easy as possible from my point of view. I did find filling out that form then making the ZIP file with all the required data somewhat irritating, but got there in the end.

But saying that - it's just for fun, there are no real prizes so if you don't officially enter but do your own little presentation then I think that's OK too.

Cheers,

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Mon Dec 25, 2023 10:18 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 690
Location: North Tejas
OK, I grit my teeth and prepared a single entry - the 6809 one because:

* it is the smallest of the four
* there is an emulator available which is very easy to install and use

Because I seriously object to being judged on the size of the source code, I spitefully compacted it:

* Removed all comments
* Removed all unnecessary white space
* Use single letter labels
* Replaced all equates with magic numbers
* FLEX text files use only a CR to separate lines, so I removed all line feed characters
* Historically, FLEX assembly language programs were written with a single space before the instruction mnemonic and a single space between it and any operand; the assembler "autofields" as it creates the listing

Because that is so danged mean, I included an assembled listing of the "normal" commented source code. The compacted source code file is less than one sixth the size of the "nice" one. Take that, stupid rule makers...

I will post the code for all four here in a little over 24 hours so that it is Boxing Day on the East side of the International Date Line.

Edit: I guess it is OK to include a screenshot...

Attachment:
REFLEX.PNG
REFLEX.PNG [ 21.34 KiB | Viewed 1620 times ]


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 26, 2023 9:38 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1926
Location: Sacramento, CA, USA
Now that it's the 26th pretty much everywhere, I just wanted to share that I only went through the trouble of submitting my WOZMON version, because the others weren't nearly as satisfying:
Code:
80:A9 FF 48 A9 1E 48 A2 FE A0 5 20 A1 0 20 93 0 20 93 0 A2 F B4 B5 20 A9 0 CA D0 F8 A2 F1 B4 C6 20
:A9 0 E8 D0 F8 A0 5 A9 A0 20 EF FF 88 D0 F8 A9 AA 4C EF FF 5 5 16 3 1 3 1 3 18 1 3 1 3 1 1A 5
80R
54 bytes of instructions plus a 16-byte table that I zig-zag through several times. I didn't use an assembler, just Notepad and an opcode map:
Code:
                x2023:
0080: A9 FF         lda #$FF
0082: 48            pha
0083: A9 1E         lda #$1E
0085: 48            pha
0086: A2 FE         ldx #$FE
0088: A0 05         ldy #5
008A: 20 A1 00      jsr xc                       ;     *     *     *;
008D: 20 93 00      jsr xx                                         ;             ;
                                        ;             * *   * *   * *            ;
                                        ;            *   * *   * *   *           ;
                                        ;           *     *     *     *          ;
                                        ;            *   * *   * *   *           ;
                                        ;             * *   * *   * *            ;
                                        ;              *     *     *;
0090: 20 93 00      jsr xx                                         ;             ;
                                        ;             * *   * *   * *            ;
                                        ;            *   * *   * *   *           ;
                                        ;           *     *     *     *          ;
                                        ;            *   * *   * *   *           ;
                                        ;             * *   * *   * *            ;
                                        ;              *     *     *;
                xx:
0093: A2 0F         ldx #$0F
                xa:                     ; 26,1,3,1,3,1,24,3,1,3,1,3,22,5,5,
0095: B4 B5         ldy table-1,x                                  ;             ;
0097: 20 A9 00      jsr spy             ;             * *   * *   * *            ;
009A: CA            dex                 ;            *   * *   * *   *           ;
009B: D0 F8         bne xa              ;           *     *     *;
009D: A2 F1         ldx #$F1
                xb:                     ; 5,22,3,1,3,1,3,24,1,3,1,3,1,26,5,
009F: B4 C6         ldy table+16,x                              ;     *          ;
                xc:
00A1: 20 A9 00      jsr spy             ;            *   * *   * *   *           ;
00A4: E8            inx                 ;             * *   * *   * *            ;
00A5: D0 F8         bne xb              ;              *     *;
                sp5:                    ; 5,
00A7: A0 05         ldy #5              ;                    ;     *;
                spy:
00A9: A9 A0         lda #" "
00AB: 20 EF FF      jsr ECHO
00AE: 88            dey
00AF: D0 F8         bne spy
00B1: A9 AA         lda #"*"
00B3: 4C EF FF      jmp ECHO
                table:
00B6: 05 05 16 03 01 03 01 03 18 01 03 01 03 01 1A 05
My solution gravitated toward a nested structure where I JSR forward into something then fall through into whatever I just JSR'd, but to keep the structure pure I had to spend an initial six bytes to feed the stack with a return address, because WOZMON doesn't provide a clean return from its "R" command. I thought about combining the "xa" and "xb" subroutines together by self-modifying, but it didn't look like it was going to pay off, so I abandoned that idea.

If there's a compact algorithmic solution which doesn't require a table, I don't have sufficient skill to find it.

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 26, 2023 12:18 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1398
Location: Scotland
barrym95838 wrote:
Now that it's the 26th pretty much everywhere, I just wanted to share that I only went through the trouble of submitting my WOZMON version, because the others weren't nearly as satisfying


Well done!

Quote:
If there's a compact algorithmic solution which doesn't require a table, I don't have sufficient skill to find it.


I think there is as that's the road I started down with alternating counts but I gave up and went for a sort of pseudo-table driven approach... So given there are only 4 unique patterns of lines it was easy to just create something compact to draw those lines then a table of what order to draw the lines in...

It went like this:

  • Design and build a retro minimal computer
  • Port Tiny Basic to it
  • Write TB code that uses a table-driven approach along the lines of one mans data being another mans program. ie. it's an interpreter for a pattern generator..
  • Run the code and submit.

This is the 'normal' code:

Code:
REM ********************************************************************
REM *       Vintage Computing Christmas Challenge 2023 (VC³ 2023)      *
REM * https://logiker.com/Vintage-Computing-Christmas-Challenge-2023   *
REM ********************************************************************

REM ********************************************************************
REM *   Gordon Henderson in GIBL - Gordons Interactive Basic Language  *
REM * Runs on home designed 6507 Retro Computer with 4K ROM and 4K RAM *
REM * ... Nothing clever, just simple lookup operations                *
REM ********************************************************************

REM Data

100 A=TOP : $A = "355"
110 B=A+8 : $B = "213131"
120 C=B+8 : $C = "131313"
130 D=C+8 : $D = "0555"
140 O=D+8 : $O = "ABCDCBABCDCBABCDCBA"

REM Loop over the "Orders" list...

150 P = O
160 X = ?P : IF X = 13 PR "" : END
170 Q = (X - 65) * 8 + A
180 GOSUB 300
190 P = P + 1
199 GOTO 160

REM Print the "Order" line

300 J = ?Q : IF J = 13 PR "" : RETURN
320 J = J - 48 : IF J = 0 GOTO 340
330 FOR K = 1 TO J : PR " "; : NEXT K
340 PR "*";
345 Q = Q + 1
350 GOTO 300


Remove spaces, comments, and compact it down and it comes to 298 bytes. Plus 4KB of TinyBasic, IO, etc. I could smush it further but couldn't be bothered.

Attachment:
result.png
result.png [ 10.48 KiB | Viewed 1575 times ]


Cheers,

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 26, 2023 1:57 pm 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 690
Location: North Tejas
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#reflex

Open 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


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 26, 2023 2:34 pm 
Offline

Joined: Mon Sep 17, 2018 2:39 am
Posts: 132
Hi!

I also used a table, but "compressed" it to 5 bytes, of which 3 bytes also are the last bytes of the code :-P

This is for the Atari XL / XE 8-bit computers, calling the put-char ROM routine and directly writing to the screen, 31 bytes total.
Code:
   org   256-E+S
S  ldy   #1
C  lda   #10
   ldx   T,y
   stx   T+6,y
R  cpx   T+4
   bne   K
   sta   (94),y
K  iny
   cpy   #20
   bne   C
   lda   #$9B
   jsr   $F2B0
T  inc   R+1
   bne   S
   rts
   .byte $FC-T+S,$D0
E  =  *+16


For the C64, the code is about 5 bytes shorter.

Have Fun!


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 26, 2023 2:41 pm 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 690
Location: North Tejas
Looking back at and trying to understand what Mike had done, I think I may be able to shrink mine a tiny bit by taking advantage of tail recursion...


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 26, 2023 2:43 pm 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 690
Location: North Tejas
dmsc wrote:
I also used a table, but "compressed" it to 5 bytes, of which 3 bytes also are the last bytes of the code :-P

That's genius!


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 26, 2023 3:37 pm 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 690
Location: North Tejas
Tail recursion proved to be of no gain in this case.

But note to self: spend less time complaining about the rules and more time optimizing.

A couple of minor restructuring changes saved five bytes from the 6*** versions:

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 8E 0021                 [3] 00069          ldx    #Top-1    ; Point to end of line before top row
                                  00070
 002A                             00071 LineLoop
 002A E6 80                   [6] 00072          ldb    ,X+       ; Get the couplet
 002C 2B 11 (003F)            [3] 00073          bmi    Special
                                  00074
 002E 27 08 (0038)            [3] 00075          beq    NoSpaces
                                  00076
 0030 86 20                   [2] 00077          lda    #' '      ; Emit spaces
                                  00078
 0032                             00079 SpaceLoop
 0032 BD CD18                 [8] 00080          jsr    PUTCHR
                                  00081
 0035 5A                      [2] 00082          decb
 0036 26 FA (0032)            [3] 00083          bne    SpaceLoop
                                  00084
 0038                             00085 NoSpaces
 0038 86 2A                   [2] 00086          lda    #'*'      ; Emit star
                                  00087
 003A BD CD18                 [8] 00088          jsr    PUTCHR
                                  00089
 003D 20 EB (002A)            [3] 00090          bra    LineLoop
                                  00091
 003F                             00092 Special
 003F 5C                      [2] 00093          incb
 0040 26 05 (0047)            [3] 00094          bne    EndImage
                                  00095
 0042 BD CD24                 [8] 00096          jsr    PCRLF     ; Start a new line
                                  00097
 0045 20 E3 (002A)            [3] 00098          bra    LineLoop
                                  00099
 0047                             00100 EndImage
 0047 8E 0001                 [3] 00101          ldx    #Image    ; Point back to start of the image
                                  00102
 004A 0A 00                   [6] 00103          dec    Count     ; Do it again?
 004C 26 DC (002A)            [3] 00104          bne    LineLoop
                                  00105
 004E 7E CD03                 [4] 00106          jmp    WARMS     ; Back to FLEX
                                  00107
 0027                             00108          end    Start


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 26, 2023 4:29 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1926
Location: Sacramento, CA, USA
dmsc wrote:
I also used a table, but "compressed" it to 5 bytes, of which 3 bytes also are the last bytes of the code :-P

This is for the Atari XL / XE 8-bit computers, calling the put-char ROM routine and directly writing to the screen, 31 bytes total.
[...]
For the C64, the code is about 5 bytes shorter.

I haven't quite finished my first cup of coffee, but I don't think any amount of coffee could allow me to understand how you did either of those very impressive feats without a much more detailed description. If you find the time and generosity, could you please try to enlighten me/us?

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 26, 2023 4:47 pm 
Offline
User avatar

Joined: Sun Nov 01, 2020 10:36 am
Posts: 35
Location: Tatooine
barrym95838 wrote:
If there's a compact algorithmic solution which doesn't require a table


I used one 8) .
I considered the whole shape as two set of diagonal stars. Each diagonal is separated by 5 spaces. So I used two counters, one for the diagonals going left, the other for the diagonals going right, and decreased the counters at each char. When either counter reaches -1 a star gets printed and that counter is reset to 5.
Three nested loops: for each line, for each char in a line, for the two counters.

It's for a C64, 45 bytes.
Code:
deccnt = $b3   ; counter for asterisks going left
inccnt = $b4   ; counter for asterisks going right
chrout = $ffd2 ; kernal routine to print a char

lines   byte $13        ; counter for the lines to be printed
start   lda #3          ; will use $b3 and $b4 zp addresses
lpLine  sta inccnt      ; $b3 already contains "3"
        ldy #19         ; # of characters in a line

lpChar  ldx #1
        lda #' '        ; check if to print space or asterisk
lpAst   dec deccnt,x    ; loops twice, for inccnt and deccnt
        bpl nx
        lda #5          ; counters go backwards from 5 to 0
        sta deccnt,x
        lda #'*'        ; a counter reached 0: print an asterisk
nx      dex
        bpl lpAst
        jsr chrout      ; print the character

        dey
        bne lpChar      ; go to compute next char of the line
       
        lda #$d
        jsr chrout      ; print newline
       
        lda #7          ; the counter going right starts a new line
        sbc deccnt      ; with a value complementary to the other counter
 
        dec lines
        bne lpLine      ; repeats for the next line

        rts


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 48 posts ]  Go to page Previous  1, 2, 3, 4  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 24 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: