| ------------------------------------------------------------------------------ | vvputsv.s -- output characters to a 4-bit / pixel graphics window | with variable vertical pitch | Version 1 -- 1988-10-07 -- D.N. Lynx Crowe | (c) Copyright 1988 -- D.N. Lynx Crowe | ------------------------------------------------------------------------------ | vvputsv(obase, nw, fg, bg, row, col, str, pitch, ht, cgtab) | uint *obase, nw, fg, bg, row, col, pitch, ht, cgtab[][256]; | char *str; | Outputs characters from the string at 'str' to an 'nw' | character wide 4-bit per pixel graphics window at 'obase' | at ('row','col'), using 'fg' as the foreground color, and | 'bg' as the background color. Uses cgtab[][256] as the | VSDD formatted character generator table. Assumes 'ht' line | high characters in the cg table. Uses 'pitch' as the vertical | spacing between character rows. No error checks are done. | The string must fit the output area (no overlaps, single line). | ------------------------------------------------------------------------------ .text .xdef vvputsv | Argument offsets from a6: OBASE = 8 | LONG - Output area base address NW = 12 | WORD - Character width of output area FG = 14 | WORD - Foreground color BG = 16 | WORD - Background color ROW = 18 | WORD - Row COL = 20 | WORD - Column STR = 22 | LONG - String base address PITCH = 26 | WORD - Vertical spacing between rows HT = 28 | WORD - Character height (LE PITCH) CGTAB = 30 | LONG - Character generator table | Program constant definitions: HPIX = 8 | Character width in pixels HCW = 4 | Horizontal character width (bytes) PSHIFT = 12 | Pixel shift into MS bits HSHIFT = 4 | Pixel right shift .page | Register usage: | d0 output word and scratch | d1 CG word and scratch | d2 pixel counter | d3 foreground color (in the 4 ms bits) | d4 background color (in the 4 ms bits) | d5 width of the area in bytes | d6 scan line counter | a0 CG table pointer | a1 output area scan line pointer | a2 input string character pointer | a3 output area character base pointer | a6 frame pointer | a7 stack pointer .page vvputsv: link a6,#0 | Link stack frames movem.l d3-d6/a3,-(a7) | Save registers we use move.w #PSHIFT,d1 | Set shift constant move.w FG(a6),d3 | Setup foreground color lsl.w d1,d3 | ... in ms 4 bits of d3.W move.w BG(a6),d4 | Setup background color lsl.w d1,d4 | ... in ms 4 bits of d4.W move.w NW(a6),d5 | Get line width in d5.W lsl.w #2,d5 | Multiply width by 4 for offset move.w ROW(a6),d0 | Calculate output address move.w PITCH(a6),d1 | ... PITCH mulu d1,d0 | ... * ROW add.w HT(a6),d0 | ... + HT-1 subq.w #1,d0 | ... mulu d5,d0 | ... * NW clr.l d1 | ... move.w COL(a6),d1 | ... + lsl.w #2,d1 | ... COL * 4 add.l d1,d0 | ... add.l OBASE(a6),d0 | ... + OBASE movea.l d0,a3 | Leave output address in a3 movea.l STR(a6),a2 | Put string address in a2 cgl0: clr.l d0 | Clear out upper bits of d0 move.b (a2)+,d0 | Get next character beq cgl5 | Done if character EQ 0 movea.l a3,a1 | Establish output pointer in a1 adda.l #HCW,a3 | Update output pointer for next char. movea.l CGTAB(a6),a0 | Establish CG pointer in a0 lsl.w #1,d0 | ... 2 * character adda.w d0,a0 | ... + cg table address move.w HT(a6),d6 | Set scan line counter in d6 subq.w #1,d6 | ... to HT-1 .page cgl1: move.w (a0),d1 | Get character generator word in d1 move.w #(HPIX/2)-1,d2 | Set pixel counter in d2 cgl2: lsr.w #HSHIFT,d0 | Shift output word right 1 pixel btst.l #0,d1 | Check CG word ls bit beq cgl3 | Set background color if bit EQ 0 or.w d3,d0 | OR foreground color into output word bra cgl4 | Go update CG word cgl3: or.w d4,d0 | OR background color into output word cgl4: lsr.w #1,d1 | Shift CG word right 1 pixel dbf d2,cgl2 | Loop for first 4 pixels move.w d0,(a1)+ | Store first output word in scan line move.w #(HPIX/2)-1,d2 | Set pixel counter in d2 cgl2a: lsr.w #HSHIFT,d0 | Shift output word right 1 pixel btst.l #0,d1 | Check CG word ls bit beq cgl3a | Set background color if bit EQ 0 or.w d3,d0 | OR foreground color into output word bra cgl4a | Go update CG word cgl3a: or.w d4,d0 | OR background color into output word cgl4a: lsr.w #1,d1 | Shift CG word right 1 pixel dbf d2,cgl2a | Loop for last 4 pixels move.w d0,(a1) | Store second output word in scan line suba.w d5,a1 | Update output pointer suba.w #2,a1 | ... adda.l #512,a0 | Update CG pointer for next scan line dbf d6,cgl1 | Loop for all scan lines bra cgl0 | Loop for next character cgl5: movem.l (a7)+,d3-d6/a3 | Restore registers unlk a6 | Unlink stack frames rts | Return to caller .end