; FASTPRN5.S - Fast character printout ; J.G.Harston, 15 March 1985 ; Print characters directly to screen bypassing ROM calls ; ======================================================= ; A very simple and fast character printout routine. ; Characters are written directly to screen memory without any ROM calls. ; It uses the Spectrum ROM's system variables for the colours, print ; location and character set location, but these can be replaced. ; ; This version: ; prints character at DFCC with colour in ATTRP ; prints block graphics and User Defined Characters ; implements movement control codes ; ; Total size: 149 bytes ; Speed: 592T per character (CHARS) ; 1031T per character (block graphics) ; 626T per character (UDC) ; +2T if print position goes over a screen third boundary ; ; WARNINGS: ; There is no check for wrapping past top or bottom of screen CHARS EQU 23606 ; Address of character set UDC EQU 23675 ; Address of user defined characters DFCC EQU 23684 ; Address in display of current position ATTRP EQU 23693 ; Current colours MEMBOT EQU 23698 ; Workspace ORG &5B00 ; Arbitary start LOAD ; Print out a character ; --------------------- ; On entry, A=character ; On exit, AF/BC/DE/HL corrupted ; PRCHAR CP 32 JR C,PRCTRL ; Jump with control codes LD DE,(CHARS) ; Get start of font CP 128 JR C,PROUT ; Jump with printable characters LD DE,(UDC) ; Get start of UDCs SUB 144 ; UDCs start at CHR$144 JR NC,PROUT ; Jump with UDCs with A=0-21 ; CHR$128-CHR$143 - block graphics ; -------------------------------- LD B,A ; Pass character to B CALL &0B38 ; Build block graphics matrix LD HL,MEMBOT ; HL=>matrix ; PO_GR1 at &0B38 builds a block graphics character matrix. ; If not using any calls in the ROM at all, insert the following code. ; LD HL,MEMBOT ; Workspace to build matrix ; PUSH HL ; LD D,A ; LD B,2 ;PRGRA1 RR D ; Get b0 or b2 ; SBC A,A ; A=&00 or &FF ; AND &0F ; A=&00 or &0F ; LD E,A ; RR D ; Get b1 or b3 ; SBC A,A ; A=&00 or &FF ; AND &F0 ; A=&00 or &F0 ; OR E ; Merge both nybbles ; LD E,4 ;PRGRA2 LD (HL),A ; Store pixel line ; INC HL ; DEC E ; JR NZ,PRGRA2 ; Loop for four lines ; DJNZ PRGRA1 ; Loop for both halves ; POP HL ; HL=>matrix JR PRMTX ; Jump to print matrix ; Print out a character matrix ; ---------------------------- ; DE=start of character set ; A=character ; PROUT LD H,0 LD L,A ADD HL,HL ADD HL,HL ADD HL,HL ; HL=char*8 ADD HL,DE ; HL=>font for character ; Print matrix ; ------------ ; HL=>8x8 character matrix ; PRMTX LD DE,(DFCC) ; DE=current print position PUSH DE ; Save print position for later LD B,8 ; 8 pixel lines PRMTXLP LD A,(HL) ; Get pixel line LD (DE),A ; Store in screen INC HL ; Step to next character line INC D ; Step to next pixel line DJNZ PRMTXLP ; Loop for 8 pixel lines POP HL ; Get print position back ; Set attribute ; ------------- PUSH HL ; Save print position LD A,H ; Convert to attribute address RRCA RRCA RRCA OR &58 LD H,A LD A,(ATTRP) ; Get current attributes LD (HL),A ; Set screen attribute POP HL ; Get print position back ; To update the print position we now fall through into CHR$9 ; ----------------------------------------------------------- PRCHR9 LD DE,+1 ; Move forward one character ; Update print position ; --------------------- PRMOVE ADD HL,DE ; Move to new position LD A,H ; Check address high byte BIT 2,A ; Adjust for wrapping past 1/3 of screen JR NZ,PRMOVE2 ADD A,7 PRMOVE2 AND &F8 ; Ensure top pixel line LD H,A LD (DFCC),HL ; Store new position RET ; Control codes ; ------------- PRCTRL CP 8 CCF ; The Spectrum colour commands fail if Carry set on exit RET NC ; Exit with control codes, with Carry clear LD HL,(DFCC) ; Get output position JR Z,PRCHR8 ; CHR$8 - back CP 10 JR C,PRCHR9 ; CHR$9 - forwards JR Z,PRCHR10 ; CHR$10 - down CP 12 JR C,PRCHR11 ; CHR$11 - up JR Z,PRCHR12 ; CHR$12 - cls CP 13 RET NZ ; CHR$13 - newline ; Cursor movement ; --------------- PRCHR13 LD A,L AND &E0 LD L,A ; Force to column 0 ; Continue to move down a line PRCHR10 LD DE,+32 ; Move forward 32 characters JR PRMOVE PRCHR11 LD DE,-32 ; Move back 32 characters JR PRMOVE PRCHR8 LD DE,-1 ; Move back one character JR PRMOVE ; Clear screen ; ------------ PRCHR12 LD HL,&4000 LD (DFCC),HL ; Set print position to (0,0) LD DE,&4001 LD BC,&1800 LD (HL),L ; Clear initial byte LDIR ; Clear display file LD BC,&2FF LD A,(ATTRP) ; Get current colours LD (HL),A LDIR ; Clear attributes RET ; Attach channel 'P' to new printout code ; --------------------------------------- ENTRY LD HL,(23631) ; CHANS LD DE,15 ADD HL,DE ; HL=>'P' output address LD DE,PRCHAR LD (HL),E INC HL LD (HL),D RET DEFW LOAD,ENTRY