Compact 64 column print routine

The place for codemasters or beginners to talk about programming any language for the Spectrum.
User avatar
djnzx48
Manic Miner
Posts: 730
Joined: Wed Dec 06, 2017 2:13 am
Location: New Zealand

Re: Compact 64 column print routine

Post by djnzx48 »

If you want to go even more extreme, you can design a font so that each row has only two possible rows that can follow it. This way each successive row can be stored in only one bit, giving a total of 7 bits per character. OK, so it might be a little hard to read, but just imagine the byte savings :)

Image
Nomad
Manic Miner
Posts: 600
Joined: Thu Dec 28, 2017 12:38 pm

Re: Compact 64 column print routine

Post by Nomad »

If you want to move away from a direct representation of an alphabet..

Why not abstract it a level and use a visual representation of Morse.. that would dramatically reduce the code size.

Image

super compact method... :lol:

Be really cold war 80s and use a combination of Morse, + one time number pad to generate your message thereby only needing the characters 0-9... Assuming you did it like a number station you would only need a few blocks of 5 digits. Very compact message encoding that way. But of course suffers from readability issues. :lol:
User avatar
Kweepa
Manic Miner
Posts: 311
Joined: Sat Feb 03, 2018 6:14 pm
Location: Albuquerque, New Mexico

Re: Compact 64 column print routine

Post by Kweepa »

I see another crap game entry!
User avatar
arkannoyed
Manic Miner
Posts: 436
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: Compact 64 column print routine

Post by arkannoyed »

Isn't it annoying when you find a way of storing data in an even more efficient and compact way, but then can't get the routine to decode it small enough to make a difference! Grrrrrr!!!!!!!!

The data is now 41 bytes for the 37 characters, but the best I can do with the print routine is 54 bytes, giving a total of 95. :x
User avatar
arkannoyed
Manic Miner
Posts: 436
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: Compact 64 column print routine

Post by arkannoyed »

So, having failed so far to get any smaller than 92 bytes, though I do have some investigating to do in terms of decoding the data format, so I might still achieve a smaller size, I thought I'd do the obvious and alter the routine to actually manage without any CHR set data.

The Character codes are actually the bitmap for each character, so 32768 possible characters! :D

The only downside is that each character code is 2 bytes. This is fine if you've only a few lines of text to display perhaps.

Now the terminating character at the end of the message just has BIT 0 set to 1.

The print routine is now 31 bytes, CALLed with BC=message address, and DE= SCReen address (-1 from the Hi-byte)

Image

Code: Select all

;interleaved 3 bit data format for 64 column text
;using the actual data for the character instead
;of the character code
;BC=message address
;DE=SCReen address -1 from the Hi-byte
;messages terminate with BIT 0 of the second byte set
;all other letters MUST have BIT 0 as 0
;
;Arkannoyed March 2018
;
;31 bytes
;
org 0fa00h

          ld bc,msg
          ld de,3f00h
start:
          ld a,(bc)            ;get msg chr byte
          ld h,a
          inc bc
          ld a,(bc)
          ld l,a
          inc bc

          push de
lp0:
          inc d
          ld a,(de)
          or 10h
          add a,a
lp1:
          add hl,hl
          adc a,a
          jr nc,lp1
          
          ld (de),a

          bit 2,d
          jr z,lp0
          
          pop de
          
          add hl,hl
          ret c

          bit 1,c
          jr nz,start
          inc e
          jr start

msg:
        db %10110111,%11011010,%11110011,%01001110,%10010010,%01001110,%10010010,%01001110 ;HELL
        db %01110110,%11011100,%00000000,%00000000,%11101001,%00100100,%01110110,%11011100 ;O TO
        db %00000000,%00000000,%01110111,%11011010,%10010010,%01001110,%10010010,%01001110 ; ALL
        db %00000000,%00000000,%01110111,%11011010,%11101001,%00100100,%00000000,%00000000 ; AT
        db %01110001,%00011100,%11010111,%01001000,%11110011,%01001110,%01110010,%01000110 ;SPEC
        db %11101001,%00100100,%11010111,%01011010,%10110110,%11011100,%10111111,%11011010 ;TRUM
        db %00000000,%00000000,%01110010,%01000110,%01110110,%11011100,%10111111,%11011010 ; COM
        db %11010111,%01001000,%10110110,%11011100,%11101001,%00100100,%11101001,%00101110 ;PUTI
        db %11010110,%11011010,%01110010,%01010110,%01001001,%00000100,%00000000,%00000001 ;NG! 
        
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2641
Joined: Mon Nov 13, 2017 3:16 pm

Re: Compact 64 column print routine

Post by Ast A. Moore »

If you align your message with a 256-byte page boundary, you can speed things up by four T states per character by replacing the two INC BCs with INC Cs.

You could also gain 5 T states by storing D temporarily elsewhere (not the stack), but that’d add two bytes to the code, and I know you wouldn’t like that. :D
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
arkannoyed
Manic Miner
Posts: 436
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: Compact 64 column print routine

Post by arkannoyed »

Yes, but I just wanted to keep it free to handle messages placed anywhere in memory, and speed isn't really the point of the exercise really! :D

I agree with you about having to PUSH/ POP stuff, irritates the hell out of me. In an ideal world, the routine would be fully relocatable, which it is, and ignore the stack completely, which it fails slightly on.

Given that your average CHR set is a few hundred bytes long, in cases where you're only perhaps going to print a few lines, and not too many different characters, even at 2 bytes per character, it'll be quite efficient. All its really doing is printing 3 x 5 bit sprites, with a 1 bit space between.

Actually this routine including the message and BC+DE to initialise it is only 109 bytes

Using the 92 byte version would add 37 bytes for the message and 6 to initialise it, giving 135 bytes!
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2641
Joined: Mon Nov 13, 2017 3:16 pm

Re: Compact 64 column print routine

Post by Ast A. Moore »

arkannoyed wrote: Thu Mar 22, 2018 1:08 pm I agree with you about having to PUSH/ POP stuff, irritates the hell out of me.
Yes, when you just need to preserve a single 8-bit register, it seems wasteful.
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
arkannoyed
Manic Miner
Posts: 436
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: Compact 64 column print routine

Post by arkannoyed »

It could actually be achieved with 1 extra byte thus

RES 2,D
dec D

instead of PUSH DE & POP DE and then no need for the stack any longer, Freeeeeeeedddddoooooooommmmmmmm!!!!! :D
User avatar
Morkin
Bugaboo
Posts: 3266
Joined: Mon Nov 13, 2017 8:50 am
Location: Bristol, UK

Re: Compact 64 column print routine

Post by Morkin »

Ast A. Moore wrote: Thu Mar 22, 2018 1:24 pm
arkannoyed wrote: Thu Mar 22, 2018 1:08 pm I agree with you about having to PUSH/ POP stuff, irritates the hell out of me.
Yes, when you just need to preserve a single 8-bit register, it seems wasteful.
Every byte is sacred...! :D
My Speccy site: thirdharmoniser.com
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2641
Joined: Mon Nov 13, 2017 3:16 pm

Re: Compact 64 column print routine

Post by Ast A. Moore »

arkannoyed wrote: Thu Mar 22, 2018 1:28 pm It could actually be achieved with 1 extra byte thus

RES 2,D
dec D

instead of PUSH DE & POP DE and then no need for the stack any longer, Freeeeeeeedddddoooooooommmmmmmm!!!!! :D
Damn clever, that! I was just thinking in more straightforward terms: LD IXh,D/LD D,IXh.
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2641
Joined: Mon Nov 13, 2017 3:16 pm

Re: Compact 64 column print routine

Post by Ast A. Moore »

Morkin wrote: Thu Mar 22, 2018 1:30 pm
Ast A. Moore wrote: Thu Mar 22, 2018 1:24 pm Yes, when you just need to preserve a single 8-bit register, it seems wasteful.
Every byte is sacred...! :D
Sir Clive gets quite ira–a–ate . . .
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
Einar Saukas
Bugaboo
Posts: 3097
Joined: Wed Nov 15, 2017 2:48 pm

Re: Compact 64 column print routine

Post by Einar Saukas »

arkannoyed wrote: Thu Mar 22, 2018 1:28 pm It could actually be achieved with 1 extra byte thus

RES 2,D
dec D

instead of PUSH DE & POP DE and then no need for the stack any longer, Freeeeeeeedddddoooooooommmmmmmm!!!!! :D
Your routine is designed to be accessed with CALL (it exits with RET) so it's implicitly using the stack anyway. I see no advantage spending an extra byte to reduce stack usage.
User avatar
arkannoyed
Manic Miner
Posts: 436
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: Compact 64 column print routine

Post by arkannoyed »

Very true!

Sometimes we all have pointless goals!
User avatar
arkannoyed
Manic Miner
Posts: 436
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: Compact 64 column print routine

Post by arkannoyed »

Same size (31 bytes), but a little bit faster as I've removed the central loop, where unrolling it is actually the same size!

Code: Select all

start:
          ld a,(bc)            ;get msg chr byte
          ld h,a
          inc bc
          ld a,(bc)
          ld l,a
          inc bc

          push de
lp0:
          inc d
          ld a,(de)
          add a,a
          add hl,hl
          adc a,a
          add hl,hl
          adc a,a
          add hl,hl
          adc a,a

          ld (de),a

          bit 2,d
          jr z,lp0
          
          pop de
          
          add hl,hl
          ret c

          bit 1,c
          jr nz,start
          inc e
          jr start
          
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2641
Joined: Mon Nov 13, 2017 3:16 pm

Re: Compact 64 column print routine

Post by Ast A. Moore »

arkannoyed wrote: Thu Mar 22, 2018 3:56 pm a little bit faster
Now we’re talking!
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Post Reply