Hiraghm,

It occurs to me there’s no point in making you or anyone search the whole 
place. So I’m just attaching that part of the thread here, so save us both the 
time. See below ...


> On Dec 29, 2020, at 19:33, Hiraghm <[email protected]> wrote:
> 
> Awhile back, someone in the list was talking about fast display routines for 
> the Model T.
> 

————  thread regarding my PAINT.SRC code for speeding up graphics. Jan. 24, 
2015 to Ken Pettit  ————

Hi, Ken,

Saw your "Any interest in this …" thread on the M100 List. I'm not fully 
functional right now (long, late night, barely into the coffee now), but it 
reminded me of a project I worked on back in '86 or '87. PG Design was 
developing the "Avant!" ROM to compete with Super ROM and other multifunction 
ROMs. It was a great idea, and my little piece of that pie was to create a 3D 
sparse-matrix spreadsheet, a Lucid-killer so to speak. I was quite proud of the 
ideas and implementation I came up with, but the whole project was eventually 
dropped as his development costs mounted.

Anyhow, to make this spreadsheet as fast as possible, I took to "painting" the 
screen myself, using only a few system ROM calls. I've forgotten many of the 
details and can't find the long-buried printed source code with comments. But I 
passed along some of the code I used for experimentation to Philip Avery in a 
couple of M100List posts back in 2006. Don't know if they're archived anywhere 
online, so I'll attempt to paste them into this message.

Be advised, I don't fully know what you're attempting, so this may not be at 
all relevant. But on the chance it might help with your project or perhaps be 
useful in some future work, here's my part of that exchange:

------------------------------------------ my first message to Philip 
-----------------------

Mike Nugent <[email protected] <mailto:[email protected]>>
To: [email protected] <mailto:[email protected]>
Reply-To: [email protected] <mailto:[email protected]>
Re: LCD prog blues

Philip,

Not knowing your ultimate purpose, I don't know if this will be of any help. I 
once had an application where I wanted to place my own characters into the LCD 
buffer and then display them as rapidly as possible, bypassing as much system 
overhead as practical while still keeping it simple.

Below is a piece of code I used in developing a solution. Because it was used 
with a much larger set of source code, and development was done completely on a 
Model 100 and/or 102, the original lacked comments. (Comments were printed on 
hard copy, but I can't put my hands on it just now, so I'm adding some from an 
admittedly faulty memory.)

PAINT.DO
-------------
;PAINT.SRC - Load LCD buffer with characters and then 'paint' them to the LCD 
display

        org     ea60h
        &equate
chrgen: equ     4622h
lcdbeg: equ     fe00h
ldirb:  equ     2542h
ldirbc: equ     6bdbh
chget:  equ     12cbh
esc$:   equ     27

        entry
start:  call    clear   ;fill LCD buffer w/spaces
        lxi     h,lcdbeg
        push    h       ;save pointer to beginning of LCD buffer
loop:   pop     h
        mvi     m,' '
        inx     h
        mvi     m,'ì'   ;ASCII 147 char. May not survive e-mail. Try mvi m,147 
instead.
        lxi     d,lcdbeg+319
        rst     3
        jnz     loopx
        lxi     h,lcdbeg
loopx:  push    h
        call    paint
        jmp     loop

                        ;This gap is almost certainly a testing artifact, where 
I altered code above
                        ;       so it never reaches this code below. Looks to 
me like up above I was
                        ;       filling the screen with that ASCII 147 
character, whereas if we
                        ;       remove some code above, it will fall through to 
here and will alternate
                        ;       between displaying two text messages.

        lxi     h,ms1   ;point to first message
        lxi     d,lcdbeg+120    ;point to where it should go in buffer (and 
thus, onscreen)
        mvi     b,ms1len        ;number of bytes in first message
        call    ldirb   ;copy message to buffer
        call    paint   ;paint buffer to screen
        call    wait    ;wait for keypress before continuing
next:   call    clear   ;clear the screen
        lxi     h,ms2   ;point to second message
        lxi     d,lcdbeg+200    ;where to position it in buffer
        mvi     b,ms2len        ;length of second message
        call    ldirb   ;copy message to buffer
        call    paint   ;paint buffer to screen
        call    wait; wait for keypress before continuing
        jmp     start   ;do it all again until ESC key is pressed

;---------- subroutines ----------

wait:   call    chget   ;wait for a keypress between screens
        jz      wait
        cpi     esc$            ;exit the program if ESC pressed
        rnz
        rst     0

clear:  lxi     h,lcdbeg        ;Clear the LCD buffer by filling with spaces
        mvi     a,' '
        mov     m,a
        lxi     d,lcdbeg+1
        lxi     b,319
        call    ldirbc  ;move 320 bytes into buffer
        ret

paint:  lxi     h,lcdbeg        ;point to beginning of LCD buffer and paint 
contents to LCD
        ;call   chrgen  ;Philip, I don't remember why this is commented out in 
my testing
        call    4601h   ;Philip, maybe this is all that was needed. If not, try 
uncommenting
        ret                     ;       the chrgen call and commenting this one.

;-------- data --------

ms1:    db      'This is message 1'
ms1len: equ     $-ms1
ms2:    db      'MESSAGE 2'
ms2len: equ     $-ms2
-----

I hope the e-mail process hasn't badly hosed the formatting; perhaps viewing in 
a monospaced font will help, though I don't know if the tabs will survive in 
any case. Maybe copy and paste into a word processor for cleanup.

I remember that the screen could be "painted" quite rapidly. The key was to 
call the ROM's chrgen routine, which does the work of displaying what you have 
in the 320-byte buffer. Regarding the call to 4601h, it had to have been 
experimental, as it wasn't in my standard list of equates. It's probably a 
subroutine inside chrgen. Maybe it worked well, maybe it didn't, and I have no 
ready way to try it these days; my development stuff is all stowed away. Just 
try using one call, then the other.

I hope this has been useful, if not to you, then to someone.

-- Nuge --

P.S. I'm sure one or more of our resident codepoets can fill in any holes. :-)


On Oct 17, 2006, at 3:53 PM, Philip Avery wrote:

> I'm stuck with this one. I'm attempting to program the LCD directly with 
> assembly and am using the book 'Hidden Powers of the M100' as a guide.
> 
> [snip]

-------------------------------------- my second message to Philip 
---------------------------

Mike Nugent <[email protected] <mailto:[email protected]>>
To: [email protected] <mailto:[email protected]>
Reply-To: [email protected] <mailto:[email protected]>
Re: LCD prog blues

I see now what I was doing with the first part of the code. I was moving a 
character, that ASCII 147, through each position of the screen. That is, I'd 
print it in position 0 (upper left), then erase it from there and print it in 
position 1, then erase it from there and put it in position 2, and so on. The 
character should appear to race through the screen, line by line, from the 
upper left corner to the bottom right corner.

I'll add new comments and a two new labels below:


PAINT.DO
-------------
;PAINT.SRC - Load LCD buffer with characters and then 'paint' them to the LCD 
display

        org     ea60h
        &equate
chrgen: equ     4622h
lcdbeg: equ     fe00h
ldirb:  equ     2542h
ldirbc: equ     6bdbh
chget:  equ     12cbh
esc$:   equ     27

        entry
start:  call    clear   ;fill LCD buffer w/spaces
;--------------------------------------------------------------------------------------------------
race:   lxi     h,lcdbeg        ;point to the beginning of LCD buffer
        push    h       ;save the position of the pointer within the buffer
loop:   pop     h       ;restore the last pointer position
        mvi     m,' '   ;erase it by putting a space there
        inx     h       ;increment the pointer to the next byte of the buffer
        mvi     m,'ì'   ;put our 'moving character' into the buffer
        lxi     d,lcdbeg+319    ;set DL register to the last byte of buffer
        rst     3       ;compare HL and DE registers
        jnz     loopx   ;they're not equal (we haven't done the whole screen 
yet)
        lxi     h,lcdbeg        ;they're equal, whole screen done, start over
loopx:  push    h       ;in either case, save the buffer pointer
        call    paint   ;paint the contents of the buffer to the LCD screen
        jmp     loop    ;continue until you're old and gray or have pressed 
SHIFT-BREAK (CTRL-C)

                        ;The code above makes an ASCII 147 character appear to 
race through
                        ;       all screen positions from upper left to lower 
right, continuing until
                        ;       execution is forcibly stopped by SHIFT-BREAK 
(CTRL-C)
                        ;       
                        ;If code from label 'race' to just before label 
'messag' is removed, then code at
                        ;       'messag' will execute, displaying alternating 
messages at predetermined
                        ;       screen positions. Pressing any key alternates 
between messages, pressing
                        ;       ESC stops execution.
;--------------------------------------------------------------------------------------------------

messag: lxi     h,ms1   ;point to first message
        lxi     d,lcdbeg+120    ;point to where it should go in buffer (and 
thus, onscreen)
        mvi     b,ms1len        ;number of bytes in first message
        call    ldirb   ;copy message to buffer
        call    paint   ;paint buffer to screen
        call    wait    ;wait for keypress before continuing
next:   call    clear   ;clear the screen
        lxi     h,ms2   ;point to second message
        lxi     d,lcdbeg+200    ;where to position it in buffer
        mvi     b,ms2len        ;length of second message
        call    ldirb   ;copy message to buffer
        call    paint   ;paint buffer to screen
        call    wait; wait for keypress before continuing
        jmp     start   ;do it all again until ESC key is pressed

;---------- subroutines ----------

wait:   call    chget   ;wait for a keypress between screens
        jz      wait
        cpi     esc$            ;exit the program if ESC pressed
        rnz
        rst     0

clear:  lxi     h,lcdbeg        ;Clear the LCD buffer by filling with spaces
        mvi     a,' '
        mov     m,a
        lxi     d,lcdbeg+1
        lxi     b,319
        call    ldirbc  ;move 320 bytes into buffer
        ret

paint:  lxi     h,lcdbeg        ;point to beginning of LCD buffer and paint 
contents to LCD
        ;call   chrgen  ;Philip, I don't remember why this is commented out in 
my testing
        call    4601h   ;Philip, maybe this is all that was needed. If not, try 
uncommenting
        ret                     ;       the chrgen call and commenting this one.

;-------- data --------

ms1:    db      'This is message 1'
ms1len: equ     $-ms1
ms2:    db      'MESSAGE 2'
ms2len: equ     $-ms2
-----
> 
> I hope the e-mail process hasn't badly hosed the formatting; perhaps viewing 
> in a monospaced font will help, though I don't know if the tabs will survive 
> in any case. Maybe copy and paste into a word processor for cleanup.
> 
> I remember that the screen could be "painted" quite rapidly. The key was to 
> call the ROM's chrgen routine, which does the work of displaying what you 
> have in the 320-byte buffer. Regarding the call to 4601h, it had to have been 
> experimental, as it wasn't in my standard list of equates. It's probably a 
> subroutine inside chrgen. Maybe it worked well, maybe it didn't, and I have 
> no ready way to try it these days; my development stuff is all stowed away. 
> Just try using one call, then the other.
> 
> I hope this has been useful, if not to you, then to someone.
> 
> -- Nuge --
> 
> P.S. I'm sure one or more of our resident codepoets can fill in any holes. :-)
> 
> 
> On Oct 17, 2006, at 3:53 PM, Philip Avery wrote:
> 
>> I'm stuck with this one. I'm attempting to program the LCD directly with 
>> assembly and am using the book 'Hidden Powers of the M100' as a guide.
>> 
>> [snip]
> 

--------------------------------------------- and the .DO file stored in my 
project's assembler files ---------------------------

This is apparently the non-experimental section intended for use in the Avant! 
ROM, though certainly subject to change, had development continued.

;PAINT.SRC

        org     ea60h
        &equate
chrgen: equ     4622h

        entry
start:  call    clear
        lxi     h,lcdbeg
        push    h
loop:   pop     h
        mvi     m,' '
        inx     h
        mvi     m,'ì'
        lxi     d,lcdbeg+319
        rst     3
        jnz     loopx
        lxi     h,lcdbeg
loopx:  push    h
        call    paint
        jmp     loop

        lxi     h,ms1
        lxi     d,lcdbeg+120
        mvi     b,ms1len
        call    ldirb
        call    paint
        call    wait
next:   call    clear
        lxi     h,ms2
        lxi     d,lcdbeg+200
        mvi     b,ms2len
        call    ldirb
        call    paint
        call    wait
        jmp     start

wait:   call    chget
        jz      wait
        cpi     esc$
        rnz
        rst     0

clear:  lxi     h,lcdbeg
        mvi     a,' '
        mov     m,a
        lxi     d,lcdbeg+1
        lxi     b,319
        call    ldirbc
        ret

paint:  lxi     h,lcdbeg
        ;call   chrgen
        call    4601h
        ret

ms1:    db      'This is message 1'
ms1len: equ     $-ms1
ms2:    db      'MESSAGE 2'
ms2len: equ     $-ms2

------------------------------------ the EQUATE.DO file I used during assembly, 
so you can figure out some of the labels ---------------------

csradr: equ     f639h
vidflg: equ     f648h
altbeg: equ     fcc0h
lcdbeg: equ     fe00h
lcd:    equ     4b44h
cls:    equ     4231h
chsns:  equ     13dbh
chget:  equ     12cbh
keyx:   equ     7270h
kyread: equ     7242h
beep:   equ     30306
lock:   equ     423fh
entrev: equ     4269h
extrev: equ     426eh
inlin?: equ     463eh
inlin:  equ     4644h
inbuf:  equ     f685h
ptill0: equ     11a2h
prt4b:  equ     1be0h
ldirbc: equ     6bdbh
lddrbc: equ     6be6h
botlft: equ     4277h
ldirb:  equ     2542h
fac1:   equ     fc18h   ;thru fc1fh
fac2:   equ     fc69h   ;thru fc70h
vartyp: equ     fb65h   ;variable type
conbyt: equ     fb8eh
hl2fac: equ     3510h
using:  equ     39ech
lc2uca: equ     0fe9h
lc2uch: equ     0fe8h
shcode: equ     ffa2h
esc$:   equ     27
ereol$: equ     'K'

------------------------------------- that's all, folks! -------------------

Sorry if the formatting sux, but I hope some of this will be helpful either now 
or someday. I'll be happy to try and remember anything else; just holler.

Best regards,

-- Nuge --

Reply via email to