1 | * ------------------------------------------------------------------------------
|
---|
2 | * vvputsv.s -- output characters to a 4-bit / pixel graphics window
|
---|
3 | * with variable vertical pitch
|
---|
4 | * Version 1 -- 1988-10-07 -- D.N. Lynx Crowe
|
---|
5 | * (c) Copyright 1988 -- D.N. Lynx Crowe
|
---|
6 | * ------------------------------------------------------------------------------
|
---|
7 | *
|
---|
8 | * vvputsv(obase, nw, fg, bg, row, col, str, pitch, ht, cgtab)
|
---|
9 | * uint *obase, nw, fg, bg, row, col, pitch, ht, cgtab[][256];
|
---|
10 | * char *str;
|
---|
11 | *
|
---|
12 | * Outputs characters from the string at 'str' to an 'nw'
|
---|
13 | * character wide 4-bit per pixel graphics window at 'obase'
|
---|
14 | * at ('row','col'), using 'fg' as the foreground color, and
|
---|
15 | * 'bg' as the background color. Uses cgtab[][256] as the
|
---|
16 | * VSDD formatted character generator table. Assumes 'ht' line
|
---|
17 | * high characters in the cg table. Uses 'pitch' as the vertical
|
---|
18 | * spacing between character rows. No error checks are done.
|
---|
19 | * The string must fit the output area (no overlaps, single line).
|
---|
20 | *
|
---|
21 | * ------------------------------------------------------------------------------
|
---|
22 | .text
|
---|
23 | *
|
---|
24 | .xdef _vvputsv
|
---|
25 | *
|
---|
26 | * Argument offsets from a6:
|
---|
27 | *
|
---|
28 | OBASE .equ 8 * LONG - Output area base address
|
---|
29 | NW .equ 12 * WORD - Character width of output area
|
---|
30 | FG .equ 14 * WORD - Foreground color
|
---|
31 | BG .equ 16 * WORD - Background color
|
---|
32 | ROW .equ 18 * WORD - Row
|
---|
33 | COL .equ 20 * WORD - Column
|
---|
34 | STR .equ 22 * LONG - String base address
|
---|
35 | PITCH .equ 26 * WORD - Vertical spacing between rows
|
---|
36 | HT .equ 28 * WORD - Character height (LE PITCH)
|
---|
37 | CGTAB .equ 30 * LONG - Character generator table
|
---|
38 | *
|
---|
39 | * Program constant definitions:
|
---|
40 | *
|
---|
41 | HPIX .equ 8 * Character width in pixels
|
---|
42 | HCW .equ 4 * Horizontal character width (bytes)
|
---|
43 | PSHIFT .equ 12 * Pixel shift into MS bits
|
---|
44 | HSHIFT .equ 4 * Pixel right shift
|
---|
45 | *
|
---|
46 | .page
|
---|
47 | *
|
---|
48 | * Register usage:
|
---|
49 | *
|
---|
50 | * d0 output word and scratch
|
---|
51 | * d1 CG word and scratch
|
---|
52 | * d2 pixel counter
|
---|
53 | *
|
---|
54 | * d3 foreground color (in the 4 ms bits)
|
---|
55 | * d4 background color (in the 4 ms bits)
|
---|
56 | * d5 width of the area in bytes
|
---|
57 | * d6 scan line counter
|
---|
58 | *
|
---|
59 | * a0 CG table pointer
|
---|
60 | * a1 output area scan line pointer
|
---|
61 | * a2 input string character pointer
|
---|
62 | *
|
---|
63 | * a3 output area character base pointer
|
---|
64 | *
|
---|
65 | * a6 frame pointer
|
---|
66 | * a7 stack pointer
|
---|
67 | *
|
---|
68 | .page
|
---|
69 | *
|
---|
70 | _vvputsv: link a6,#0 * Link stack frames
|
---|
71 | movem.l d3-d6/a3,-(a7) * Save registers we use
|
---|
72 | move.w #PSHIFT,d1 * Set shift constant
|
---|
73 | move.w FG(a6),d3 * Setup foreground color
|
---|
74 | lsl.w d1,d3 * ... in ms 4 bits of d3.W
|
---|
75 | move.w BG(a6),d4 * Setup background color
|
---|
76 | lsl.w d1,d4 * ... in ms 4 bits of d4.W
|
---|
77 | move.w NW(a6),d5 * Get line width in d5.W
|
---|
78 | lsl.w #2,d5 * Multiply width by 4 for offset
|
---|
79 | move.w ROW(a6),d0 * Calculate output address
|
---|
80 | move.w PITCH(a6),d1 * ... PITCH
|
---|
81 | mulu d1,d0 * ... * ROW
|
---|
82 | add.w #HT(a6),d0 * ... + HT-1
|
---|
83 | subq.w #1,d0 * ...
|
---|
84 | mulu d5,d0 * ... * NW
|
---|
85 | clr.l d1 * ...
|
---|
86 | move.w COL(a6),d1 * ... +
|
---|
87 | lsl.w #2,d1 * ... COL * 4
|
---|
88 | add.l d1,d0 * ...
|
---|
89 | add.l OBASE(a6),d0 * ... + OBASE
|
---|
90 | movea.l d0,a3 * Leave output address in a3
|
---|
91 | movea.l STR(a6),a2 * Put string address in a2
|
---|
92 | *
|
---|
93 | cgl0: clr.l d0 * Clear out upper bits of d0
|
---|
94 | move.b (a2)+,d0 * Get next character
|
---|
95 | beq cgl5 * Done if character EQ 0
|
---|
96 | *
|
---|
97 | movea.l a3,a1 * Establish output pointer in a1
|
---|
98 | adda.l #HCW,a3 * Update output pointer for next char.
|
---|
99 | movea.l CGTAB(a6),a0 * Establish CG pointer in a0
|
---|
100 | lsl.w #1,d0 * ... 2 * character
|
---|
101 | adda.w d0,a0 * ... + cg table address
|
---|
102 | move.w HT(a6),d6 * Set scan line counter in d6
|
---|
103 | subq.w #1,d6 * ... to HT-1
|
---|
104 | *
|
---|
105 | .page
|
---|
106 | cgl1: move.w (a0),d1 * Get character generator word in d1
|
---|
107 | move.w #(HPIX/2)-1,d2 * Set pixel counter in d2
|
---|
108 | *
|
---|
109 | cgl2: lsr.w #HSHIFT,d0 * Shift output word right 1 pixel
|
---|
110 | btst.l #0,d1 * Check CG word ls bit
|
---|
111 | beq cgl3 * Set background color if bit EQ 0
|
---|
112 | *
|
---|
113 | or.w d3,d0 * OR foreground color into output word
|
---|
114 | bra cgl4 * Go update CG word
|
---|
115 | *
|
---|
116 | cgl3: or.w d4,d0 * OR background color into output word
|
---|
117 | *
|
---|
118 | cgl4: lsr.w #1,d1 * Shift CG word right 1 pixel
|
---|
119 | dbf d2,cgl2 * Loop for first 4 pixels
|
---|
120 | *
|
---|
121 | move.w d0,(a1)+ * Store first output word in scan line
|
---|
122 | move.w #(HPIX/2)-1,d2 * Set pixel counter in d2
|
---|
123 | *
|
---|
124 | cgl2a: lsr.w #HSHIFT,d0 * Shift output word right 1 pixel
|
---|
125 | btst.l #0,d1 * Check CG word ls bit
|
---|
126 | beq cgl3a * Set background color if bit EQ 0
|
---|
127 | *
|
---|
128 | or.w d3,d0 * OR foreground color into output word
|
---|
129 | bra cgl4a * Go update CG word
|
---|
130 | *
|
---|
131 | cgl3a: or.w d4,d0 * OR background color into output word
|
---|
132 | *
|
---|
133 | cgl4a: lsr.w #1,d1 * Shift CG word right 1 pixel
|
---|
134 | dbf d2,cgl2a * Loop for last 4 pixels
|
---|
135 | *
|
---|
136 | move.w d0,(a1) * Store second output word in scan line
|
---|
137 | suba.w d5,a1 * Update output pointer
|
---|
138 | suba.w #2,a1 * ...
|
---|
139 | adda.l #512,a0 * Update CG pointer for next scan line
|
---|
140 | dbf d6,cgl1 * Loop for all scan lines
|
---|
141 | *
|
---|
142 | bra cgl0 * Loop for next character
|
---|
143 | *
|
---|
144 | cgl5: movem.l (a7)+,d3-d6/a3 * Restore registers
|
---|
145 | unlk a6 * Unlink stack frames
|
---|
146 | rts * Return to caller
|
---|
147 | *
|
---|
148 | .end
|
---|