News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

CPM+ fast text program

Started by mchantler, 17:04, 09 February 16

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

mchantler


Hello All,
Is anyone interested in a program to speed up text writes to screen?

Thought I'd write one partly for fun and hoped it might be useful
(I heard that there was one already but couldn't find it anywhere)


Now to the lowering of expectations it's not lightening fast, but a noticeble improvement
For me using VDE editor is now a lot nicer!


How it works is in 3 parts
   An initial loader at 0100H that copies a 2nd loader into bank 3
   Then it pages RAM and changes the firmware jumpblock of BB5A/D to point to new routines


   The 3rd part is the CP/M RSX which contains the new routines, but does nothing as far as
   CP/M is aware. The cool part about the RSX is it relocates the code for you so all the jumps and
   addresses are automatically changed depending on the TPA that's free (ie other RSX's loaded)
   (The only reason I used RSX was to reserve some memory for the
   program to live, nowhere is free or safe in 1st 64k bank, I know I tried it and program always getting clobbered by something)


   TPA is reduced by 300-400 bytes. Recommend making this the 1st RSX loaded..


I will attach all the source code but today I have just got it to work so its not ready to share yet


Please let me know any bugs or any comments!
I haven't tried it with other RSX's loaded yet (XSUB?), but it works ok with dBase and WordStar


Martin

||C|-|E||

This is interesting. Does it increase the speed at which you can write or the speed at which the computer prints the texts? As far as I understood, this could be used with any text program once it is "installed" right?  :)

mchantler

Hi, yes that's right, any text program will display faster (in theory)
it increases speed of the printing of text. the firmware routines have to cope with all the basic screen functions, text windows, colours, modes, udf symbols. cp/m is just mode 2. i was testing it and found the firmware routine is about 1500 cycles and could get to around 300-400 cycles with strip down routine.


unfortunately the speed boost doesnt reflect that, theres still something slow there somewhere, or maybe the cp/m programs redraw a lot of characters the way they update the screen.


i did find one program that didn't work was disckit. this is not a true cp/m program so is hardly suprise and its mode 1 which my code doesn't handle
need to put something in so disckit will work, well.. maybe, a user can always reload cp/m to save me having to do this lol. i'm much more concerned about cpm programs not working though that would b a worry



Martin

ZbyniuR

I have scan of program FastScreen for CP/M from Polish magazine "Bajtek".
Maybe it help. Sorry, I have working version of this only for AmsDOS.

Or if you have some ROMBOX just use XD-DOS, to have FastPrint just after reset. :)
In STARS, TREK is better than WARS.

||C|-|E||

I was thinking to use something like this for our adventure but, sadly, it is in Mode 1...  :doh: However. is still very cool for many other things  :)

mchantler

ah i see, well if there's not one out there (who knows! Zbyniu found 2 already lol). there used to be one called 'fast text' back in the day as well, for amsdos
i could do a mode 1 version. if column/row positioning is good enough it would be little work.


for the source code i will put this online tommorow i found a few things to put right first. and to comment properly. it was real hard to find all the pieces of puzzle to make it work (mainly cp/m stuff, and ram and rom bank switching).






mchantler


as promised here's the source code in a DSK file with an updated COM that should be a tiny bit faster! 


for other assembly projects it does RAM and ROM bank switching that might give clues if your stuck on this
also it handles the CRTC offset for calculating screen roll which cause curses to fly from my mouth but is really simple in the end
for CPM its a big clue how to build programs and RSX resident programs. not too much out there on this in the way of source code


put on all the system programs you'd need to build it except the assembler. Z80ASM you can get this from google not sure the CPC wiki policy on ancient softwares ;)


Put VDE on there also
next i want to speed up scrolling in VDE which i have plan for cause i plan to do a lot more CPM stuff next project. this OS is really impressive and i missed out on it back in the day. gonna do all the CPM work on the CPC


really chuffed to get this done finally did something for the CPC! even if it's only a tiny piece of work of limited appeal,


Martin


mchantler





; FAST-TEXT CP/M FOR AMSTRAD CPC
; MCHANTLER '16. Feel free to use for any purpose
;
; Version 1.0 - First release
; V1.1 - Re-write control char handling, remove redundant checks
;
; Replaces original character display routine with a faster one
;
; This is the initial loader, the main routine is bolted onto the COM file
; as an RSX. But this is compiled normally with Z80ASM FTXT




.RADIX 16     ; Default to hex numbers


              TOTAL EQU (THEEND-ZOOM) ; Total bytes from ZOOM to END


             
              ; LOW LOADER. This only bit that stays at 100H
              ORG 0100H           ; CP/M start of TPA
START:
              LD DE, 0C000        ; first we have to relocate to bank 3
              LD HL, ZOOM         ; because CPM runs all in 2nd 64K
              LD BC, TOTAL        ; zoom up to a free part of the TPA
              LDIR                ; copy second loader there
              CALL 0C000          ; fly to the moon
              LD DE, MESG         ; display message it hasnt crashed
              LD C, 9             ; BDOS routine 9. Prints text
              CALL 5              ; Call BDOS
              JP 0                ; Warm boot the CCP, instead of RET
MESG:         DEFM "Fast Text CP/M Installed v1.1$"




              ; HIGH LOADER. Runs in bank 3
              ; C000 is the start of bank 3 and over 10k below the end of
              ; TPA. Even with several RSX loaded this should be free
              ; So no need to check the actual size of TPA
ZOOM:
     DI                           ; In case interrupt doesnt like RAM paging


     LD HL, (6)                   ; Get first address in RSX/BDOS chain
     INC HL                       ; This is the address in 6 and 7
     LD A, (HL)                   
     INC HL
     LD H, (HL)
     LD L, A                      ; HL now contains first RSX or BDOS entry


     LD A, 0C1                    ; page in original 64K except bank 3
     LD BC, 07F00                 ; which stays CPM
     OUT (C), A


     LD A, 0C3                    ; patch firmware jumpblock
     LD (0BB5A), A                ; FOR BB5A - Acts on control codes
     LD (0BB5D), A                ; AND BB5D - Doesn't act on control codes


     LD DE, 00003                 ; BB5D is 3 bytes beyond RSX code start
     ADD HL, DE                   ; first 3 are a jump up the RSX/BDOS chain
     LD (0BB5E), HL               ; as it intercepts no BDOS calls
     LD E, 00D                    ; BB5A is a further 13
     ADD HL, DE
     LD (0BB5B), HL               ; jumpblock now patched


     LD BC, 07F00                 ; page RAM back to C2 for all banks CP/M
     LD A, 0C2                    ; this took 3 days to figure out
     OUT (C), A                   ; now is making sense!
     EI
     RET




THEEND:       NOP


END







; FAST-TEXT CP/M FOR AMSTRAD CPC V1.1                         MCHANTLER '16
;
; This is the second part which contains the main routine
;
; Its an RSX, to compile:
;    Z80ASM FTXTRSX/M    - to create Microsoft relocate file
;    LINK FTXTRSX [OP]   - to create PRL file. LINK is on 6128 CP/M disk
;    PIP FTXTRSX.RSX=FTXTRSX.PRL - rename to RSX extension
;    GENCOM FTXT FTXTRSX - to join the two into one COM file


.RADIX 16     ; DEFAULT TO HEX NUMBERS


             
; NEW ROUTINE CODE
; Preserves all registers apart from AF which seems ok




; RSX prefix
              DEFB 0,0,0,0,0,0    ; Serial no of OS. Auto-filled by CP/M
              JP START            ; Start of program jump
NEXT:         DEFB 0C3            ; Jump next RSX/BDOS in chain. Auto-filled
              DEFW 0
              DEFW 0              ; Previous one. Not set as per DR example
              DEFW 0              ; Remove flag 0, nonbank 0
              DEFM "FTXTCPM "     ; RSX name
              DEFB 0,0,0          ; Loader flag + reserved




START:
              JP NEXT             ; BDOS chain. No intercept so just a jump


;PATCHED BB5D ENTRY POINT. Any changes here need to update firmware BB5A patch
PBB5D:                            ; entry point
              PUSH BC             ; preserve BC
              PUSH HL             ; and HL
              CP 20               ; SPACE char has own routine
              JP Z, SPACE
              LD L, A             ; L holds char to display below
              LD BC, BB5D         ; jumps to BC to call original
              JR CHECK            ; skip to check code


;PATCHED BB5A ENTRY POINT
PBB5A:
              PUSH BC             ; preserve BC
              PUSH HL             ; and HL


              ; If we might be in a control char parameter set use original
              LD L, A             ; copy char to display to L
              LD C, 0             ; default C to 0 meaning all ok
              LD A, (CTLCOUNT)    ; get last control counter
              OR A                ; if its 0 were ok
              JP Z, CTLOK         ; skip to next bit. JP faster than JR
              LD C, 1             ; 1 means use original
              DEC A               ; decrease counter
              LD (CTLCOUNT), A    ; and store
              JP CTLSKIP          ; skip Space check so use original for space


CTLOK:        LD A, L             ; restore char to display to A
              CP 20               ; SPACE char has own routine
              JP Z, SPACE


CTLSKIP:      LD A, L             ; see if char to display is control char
              CP 20
              JP NC, CONTINUE     ; if not skip
              LD C, 1             ; use original
              LD A, 2             ; set last countrol counter to 2 so next
              LD (CTLCOUNT), A    ; 2 characters use original routine


CONTINUE:


              LD A, C             ; if C=1 then control chars mean
              CP 1                ; use original
              LD BC, BB5A         ; original address to run
              JP Z, ORIG          ; run original if C=1
               
CHECK:        ; note, extra testing here
              ; remmed out some checks that might not be needed
              ; these were needed during original testing in Amsdos
              ; but seem to work ok in CP/M
             ;LD A, (0B727)       ; get cursor X pos. 6128 only
             ;CP 04F---           ; 79. if at end of line let original handle
             ;JR Z, ORIG---       ; old check. this seems to work ok
             ;LD A, (LASTY)       ; get cursor Y pos of last char displayed
             ;LD H, A             ; store in H
             ;LD A, (0B726)       ; get current cursor Y pos
             ;LD (LASTY), A       ; and update last Y pos with the current
             ;CP H                ; if different let original handle
             ;JR NZ, ORIG         ; at end of screen original does extra stuff
             ;CP 019              ; screen line 25 is actually 26 if more use
             ;JP C, MAIN          ; original also
              JP MAIN


ORIG:         ;checks mean must run original to handle control chars
              LD (ORIGAD), BC     ; store jump to address with which to run
              LD A, L             ; restore char to print to A
              POP HL              ; restore registers
              POP BC
              DEFB 0C3            ; C3 jump to run original routine
ORIGAD:       DEFW 0000           ; with address from BC




; Checks passed, use fast text routine


MAIN:         DI                  ; for speed + interrupts and bank switching
              PUSH DE             ; preserve. all now preserved apart from AF
              LD BC, 07F8A        ; page in lower ROM, leave upper disabled
              OUT (C), C
              LD H, 0             ; char to print is now in HL
              ADD HL, HL          ; multiply HL by 8
              ADD HL, HL          ; to get the char bitmap
              ADD HL, HL          ; starting offset
              LD DE, 03800        ; char bitmap start address in ROM
              ADD HL, DE          ; our char base address
              EX DE, HL           ; free HL, char base now in DE
              LD HL, ROWADR       ; lookup table of screen row addresses
              LD BC, (0B726)      ; cursor Y pos. 6128 only
              LD B, 0             ; zero B cause only 1 byte
              ADD HL, BC          ; find row address in lookup table
              ADD HL, BC          ; do twice as 2 byte values
              LD A, (HL)          ; get address value in HL into HL
              INC HL              ; HL now points to screen address for this
              LD H, (HL)          ; cursor row position
              LD L, A
              LD BC, (0B727)      ; get cursor X pos. 6128 only
              LD B, 0
              ADD HL, BC          ; add X pos to screen address directly
              LD BC, (0B7C4)      ; get CRTC offset
              ADD HL, BC          ; add to screen address to correct it
              RES 3, H            ; take off 2048 to futher adjust
              LD BC, 00800        ; 2048 is screen line offset


              ; All now ready to write the character
              LD A, (DE)          ; line 1. DE=char source. HL=screen address
              LD (HL), A          ; this is quicker than a loop or using LDI
              INC DE
              ADD HL, BC         
              LD A, (DE)          ; line 2.                               
              LD (HL), A          ; write to screen
              INC DE              ; next line of char bitmap
              ADD HL, BC          ; next line of screen
              LD A, (DE)          ; line 3
              LD (HL), A
              INC DE
              ADD HL, BC
              LD A, (DE)          ; line 4
              LD (HL), A
              INC DE
              ADD HL, BC
              LD A, (DE)          ; line 5
              LD (HL), A
              INC DE
              ADD HL, BC
              LD A, (DE)          ; line 6
              LD (HL), A
              INC DE
              ADD HL, BC
              LD A, (DE)          ; line 7
              LD (HL), A
              INC DE
              ADD HL, BC
              LD A, (DE)          ; line 8
              LD (HL), A


              ; now handle invert, this will make inverted chars slower
              ; but normal ones stay at max possible speed
              LD A, (0B72F)       ; 6128 pen colour
              OR A                ; reset carry for SBC below and check if 0
             
INVERT        JP NZ,INVSKIP       ; if not 0 its normal, skip...
              LD D, B             ; copy 2048 in BC to DE
              LD E, C
              LD B, 008           ; setup B with qty for loop


                 
INVLOOP:      LD A, (HL)          ; get screen contents to A
              CPL                 ; invert
              LD (HL), A          ; store back to screen
              SBC HL, DE          ; take off 2048
              DJNZ INVLOOP        ; do for 8 lines




INVSKIP:      LD HL, 0B727        ; add 1 to cursor X
              INC (HL)           
             
              LD BC, 07F8E        ; disable lower rom and upper rom
              OUT (C), C
              POP DE              ; restore registers
              POP HL
              POP BC
              EI
              RET




; Special routine just for the space for extra speed


SPACE:
              DI
              PUSH DE             ; preserve DE
              LD HL, ROWADR       ; screen row addresses
              LD BC, (0B726)      ; cursor Y
              LD B, 0
              ADD HL, BC          ; find screen address for Y
              ADD HL, BC          ; twice as 2 byte values
              LD A, (HL)          ; get address into HL
              INC HL
              LD H, (HL)
              LD L, A
              LD BC, (0B727)      ; cursor X position
              LD B, 0
              ADD HL, BC          ; add on
              LD BC, (0B7C4)      ; CRTC offset
              ADD HL, BC          ; add on to adjust
              RES 3, H            ; take off 2048 if bit is set
              LD BC, 00800        ; 2048 screen line offset
              LD A, (0B72F)       ; get current pen colour
              CPL                 ; turn 0 to FF, FF to 0
              LD (HL), A          ; line 1. write to screen
              ADD HL, BC          ;
              LD (HL), A          ; line 2
              ADD HL, BC
              LD (HL), A          ; line 3
              ADD HL, BC
              LD (HL), A          ; line 4
              ADD HL, BC
              LD (HL), A          ; line 5
              ADD HL, BC
              LD (HL), A          ; line 6
              ADD HL, BC
              LD (HL), A          ; line 7
              ADD HL, BC
              LD (HL), A          ; line 8
              LD HL, 0B727        ; increase cursor X pos by one
              INC (HL)
              POP DE              ; restore registers
              POP HL
              POP BC
              EI
              RET


; calls to original firmware routines
BB5A:
              RST 08
              DEFB 0FE, 093
              RET


BB5D:         RST 08
              DEFB 035,093
              RET


; table of row addresses for each 25 lines
; CP/M screen starts at 4000 not C000!
ROWADR:       DEFW 04000          ; screen address for all 25 rows
              DEFW 04050          ; a bit quicker than multiplying Y by 80
              DEFW 040A0
              DEFW 040F0
              DEFW 04140
              DEFW 04190
              DEFW 041E0
              DEFW 04230
              DEFW 04280
              DEFW 042D0
              DEFW 04320
              DEFW 04370
              DEFW 043C0
              DEFW 04410
              DEFW 04460
              DEFW 044B0
              DEFW 04500
              DEFW 04550
              DEFW 045A0
              DEFW 045F0
              DEFW 04640
              DEFW 04690
              DEFW 046E0
              DEFW 04730
              DEFW 04780


;LASTY:        DEFB 00             ; keeps track of previous cursor Y pos
CTLCOUNT:     DEFB 00             ; counter for control character handling


THEEND:       NOP


END



ZbyniuR

This is not for CP/M, but maybe someone need it.

FastSreen - for AmsDOS (but 6128 only) scan from the same "Bajtek", and ...
      working version on DSK together with SpeedDisk. As you see on screen I hate DATA  line, because I prefer shorter program. ;)  FS without SD could be in 1 line of Basic. yey :D   In this version steel working CHR$(22)  Ctrl+V, oposite to others similar programs.

And scan FastPrint from other Polish magazine "Komputer" 12-88 & 4-89. Version for 6128 and 464 with RSX:  |ITALIC   |UNDERLINE   |INVERSE  but I never tested this.
In STARS, TREK is better than WARS.

mchantler

that is really cool zbyniu, that should cover all the fast text routines anyone should want. although there's still the original 'fast text' i remember from one of scully's pd disks that worked in basic. anyone remember it?


for the cp/m the speed up v1.2 is now ready with com file attached!
this one speeds up scrolling in vde with a hardware scroll
it will work in any editor that sets up a window and scrolls the whole 80 columns with 1 row at the top for a status bar. i know its a bit restrictive at present. but easy to change for more top rows, but not for less than 80 cols wide
PS I would not have started this mod if i knew how hard it was gonna be.. the way the screen offset wraps round you think it's working then noooooo, its all wrong and start again


there's some flickering around the top and bottom. i dont really care tho, coz its 3 times faster scrolling!
i dont really know how to stop it doing this. if i could somehow know when to wait for the right moment


ps i have one more idea to speed things up further, to try and bypass the bios for screen writes and see what happens


mart





SRS

Did you take a look at the dobbertin disk FAST.COM, too - it is fast text for CPM+ ?

And for amsdos of course this from wiki here:http://cpcwiki.eu/index.php/Programming:Fast_Textoutput

Maybe you can find a twist or two to get your prog even faster :)


mchantler

hmm, from what i could find it looks like you need the vortex expansion to run the fast text on dobbertin as it supports all kind of character sets. so i'm guessing these reside on the rom that comes with this expansion. it looks like a really good patch and comprehensive feature set! maybe this could be a way to go also if you want quicker cp/m! i don't know the steps involved to actually get this running, say on winape, to try it
but it proves it can be done  (i will ignore the fact you can speed up emulators.. that, is cheating lol)


what i really want is to get back into z80 again so this fast text thing ties in with quicker editing of source code, with the text slowness improved and 800k drive b:, the cpc is a great cp/m machine, for developing in assembler or c and doing cool projects. or checking out the vast cpm archives. i think that pretty exciting thing you can do with a cpc today. future retro-head type dudes will look at which emulator/machine to start hacking around with .. yep, cpc has got to be one of the better choices for exploring the 8 bit universe!

mchantler

 :doh:  ignore what i said about vortex. didn't see the dsk file attached, fired it up and fast.com works!
did a comparison and Dobbertin's a % or two quicker (beaten!) on pure text display. hardware scroll of v1.2 does make line by line navigating faster but dont think its possible to really go beyond the text display times.. still one more thing to try though




Powered by SMFPacks Menu Editor Mod