1 /*
2   Print
3 */
4 
5 #include "print.h"
6 
7 #include "addr.h"
8 #include "console.h"
9 #include "head.h"
10 #include "jump.h"
11 #include "mem.h"
12 #include "message.h"
13 #include "object.h"
14 #include "os.h"
15 #include "page.h"
16 #include "pc.h"
17 #include "shared.h"
18 #include "wio.h"
19 
20 static word buff[MAX_SLACK];
21 static int buff_held, buff_width;
22 
init_print(void)23 void init_print(void)
24 {
25   extern int linecount;
26   extern bool enable_screen;
27   extern bool disable_script;
28 
29   extern void (*PrintChar) (word);
30   extern bool windowing_enabled;
31   extern word current_window;
32   extern bool use_buffered_io;
33 
34   linecount         = 0;
35   enable_screen     = 1;
36   disable_script    = 0;
37   PrintChar         = print_char;
38   buff_held         = 0;
39   buff_width        = 0;
40   windowing_enabled = 0;
41   current_window    = 0;
42   use_buffered_io   = 1;
43 }
44 
measure(word ch)45 static void measure(word ch)
46 {
47   if(kind(ch) != 0)
48     out_char(ch);
49   else
50     buff_width += char_width(ch);
51 }
52 
print_buffer(int count)53 static void print_buffer(int count)
54 {
55   int i;
56   start_update();
57   for(i = 0; i < count; ++i)
58     out_char(buff[i]);
59   finish_update();
60   os_mcpy(buff, buff + count, (buff_held -= count) * sizeof(*buff));
61   for(i = buff_width = 0; i < buff_held; ++i)
62     measure(buff[i]);
63 }
64 
flush_prt_buff(void)65 void flush_prt_buff(void)
66 {
67   extern int linecount;
68   print_buffer(buff_held);
69   linecount = 0;
70 }
71 
print_num(word number)72 void print_num(word number)
73 {
74   extern void (*PrintChar) (word);
75   int num;
76 
77   if(number == 0)
78     (*PrintChar) ((word) '0');
79   else
80   {
81     num = (signed_word) number;
82     if(num < 0)
83     {
84       num = -num;
85       (*PrintChar) ((word) '-');
86     }
87     PrintNumber(num);
88   }
89 }
90 
PrintNumber(int num)91 void PrintNumber(int num)
92 {
93   extern void (*PrintChar) (word);
94 
95   if(num > 9) PrintNumber(num / 10);
96   (*PrintChar) ('0' + num % 10);
97 }
98 
print2(word packed)99 void print2(word packed)
100 {
101   long_word addr = ad_text_addr(packed);
102   word page      = pg_page(addr);
103   word offset    = pg_offset(addr);
104   print_coded(&page, &offset);
105 }
106 
print1(word address)107 void print1(word address)
108 {
109   word page   = pg_page(address);
110   word offset = pg_offset(address);
111   print_coded(&page, &offset);
112 }
113 
wrt(void)114 void wrt(void)
115 {
116   word page   = pc_page();
117   word offset = pc_offset();
118   print_coded(&page, &offset);
119   set_pc(page, offset);
120 }
121 
writeln(void)122 void writeln(void)
123 {
124   wrt();
125   new_line();
126   ret_true();
127 }
128 
new_line(void)129 void new_line(void)
130 {
131   print_buffer(buff_held);
132   out_char('\n');
133 }
134 
print_char(word ch)135 void print_char(word ch)
136 {
137   extern bool use_buffered_io;
138   extern bool use_internal_buffer;
139   extern long_word internal_io_buffer;
140   extern word int_io_buff_length;
141   extern word current_window;
142 
143   if(use_internal_buffer)
144   {
145     wr_byte_addr(internal_io_buffer + 2 + int_io_buff_length++, ch);
146   }
147   else if(!use_buffered_io || current_window != 0)
148   {
149     out_char(ch);
150   }
151   else
152   {
153     buff[buff_held++] = ch;
154     measure(ch);
155     if(buff_width >= display_width()
156     || buff_held >= MAX_SLACK)
157     {
158       int i = buff_held - 1;
159       while(i >= 0 && buff[i] != ' ')
160         --i;
161       out_char('\f');
162       print_buffer(i >= 0 ? i+1 : buff_held);
163       out_char('\n');
164     }
165   }
166 }
167