UrForth: properly mark scattered colon words
[urasm.git] / libs / winsys / winprint.zas
blobf7ba17a01e752b589d7de5a9450a1e266db49649
1   module WinPrint
2   ;; requires: WinSys, WinFont
4 ch_cls:        equ 12
5 ch_right:      equ 26
6 ch_center:     equ 27
7 ch_at:         equ 28
8 ch_nextp:      equ 29
9 ch_attr:       equ 30
10 ch_rep:        equ 31
11 ch_bigspc:     equ 255
12 ch_smallspc:   equ 246
13 ch_smallradio: equ 247
14 ch_smallradio0:equ 247
15 ch_smallradio1:equ 248
16 ch_bigradio:   equ 249
17 ch_bigradio0:  equ 249
18 ch_bigradio1:  equ 250
19 ch_smallcheck: equ 253
20 ch_smallcheck0:equ 253
21 ch_smallcheck1:equ 254
22 ch_bigcheck:   equ 251
23 ch_bigcheck0:  equ 251
24 ch_bigcheck1:  equ 252
27 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28 ;; get asciiz string width
29 ;; in:
30 ;;   hl: string address
31 ;; out:
32 ;;   c: width
33 ;;   hl: ptr to "terminator char"
34 ;;   af, b, de: destroyed
35 ;; actually, the string terminates by any char with code <= #1D(29)
36 GetTextWidth:
37   ld    c,0
38 .loop:
39   ld    a,(hl)
40   cp    #1E
41   ret   c
42   inc   hl
43   jr    nz,.not1E
44   ; #1E(30): set attrs to (next_byte)
45   inc   hl
46   jr    .loop
47 .not1E:
48   ld    b,1  ; count
49   cp    #1F
50   jr    nz,.sum
51   ; #1F(31): print (next_byte) charz with the code taken from (next_byte+1)
52   ld    b,(hl)
53   inc   hl
54   ld    a,(hl)
55   inc   hl
56 .sum:
57   push  hl
58   ld    hl,(WinFont.chars)
59   ld    e,a
60   ld    d,0
61   add   hl,de
62 .sum_loop:
63   ld    a,(hl)
64   add   a,c
65   ld    c,a
66   djnz  .sum_loop
67   pop   hl
68   jr    .loop
71 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
72 ;; print asciiz string
73 ;; in:
74 ;;   hl: string address
75 ;;     special charz:
76 ;;       1..#19(25): new line
77 ;;       #0C(12): "cls"
78 ;;       #1A(26): "right" the next substring; end of substring: 0..#1C
79 ;;       #1B(27): "center" the next substring; end of substring: 0..#1C
80 ;;       #1C(28): at -- x=(next_byte); y=(next_byte+1) (y in charz); y>127: don't change
81 ;;       #1D(29): move to the next attr pos (mainly used when changing attrz)
82 ;;       #1E(30): set attrs to (next_byte)
83 ;;       #1F(31): print (next_byte) charz with the code taken from (next_byte+1)
84 ;; out:
85 ;;   af,af',bc,de: destroyed
86 ;;   hl: address of the first char after the end of the string
87 PrintStrZ:
88   ld    a,(hl)
89   inc   hl
90   or    a
91   ret   z
92   cp    #1F
93   jr    z,.do1F
94   jr    c,.ctrl
95   call  PrintChar
96   jr    PrintStrZ
97 .do1F:
98   ; #1F(31): print (next_byte) charz with the code taken from (next_byte+1)
99   ld    b,(hl)
100   inc   hl
101 .do1F_loop:
102   ld    a,(hl)
103   call  PrintChar
104   djnz  .do1F_loop
105   inc   hl
106   jr    PrintStrZ
107 .ctrl:
108   cp    #1D
109   jr    c,.less1D
110   jr    nz,.do1E
111   ; #1D(29): move to the next attr pos
112   ld    de,WinSys.printxy
113   ld    a,(de)
114   and   #07
115   ld    a,#ff         ; #ff is the empty square; width=8
116   call  nz,PrintChar
117   ld    a,(de)
118   and   #F8
119   ld    (de),a
120   jr    PrintStrZ
121 .do1E:
122   ; #1E(30): set attrs to (next_byte)
123   ld    a,(hl)
124   inc   hl
125   ld    (WinSys.attr),a
126   jr    PrintStrZ
127 .less1D:
128   cp    #1C
129   jr    nz,.do1A1B
130   ; #1C(28): at -- x=(next_byte); y=(next_byte+1) (y in charz)
131   ld    e,(hl)
132   inc   hl
133   ld    d,(hl)
134   inc   hl
135   ld    (WinSys.printxy),de
136   jr    PrintStrZ
137 .do1A1B:
138   cp    #1A
139   jr    c,.iscls
140   ; #1A(26): "right" the next substring; end of substring: 0..#1C
141   ; #1B(27): "center" the next substring; end of substring: 0..#1C
142   ; calc string width
143   push  hl
144   ex    af,af'
145   call  GetTextWidth
146   pop   hl
147   ; calc right x coord
148   ld    a,(WinSys.wsize)
149   add   a,a
150   add   a,a
151   add   a,a
152   sub   c
153   ld    e,a
154   ex    af,af'
155   ld    a,e
156   jr    z,.ok1A
157   or    a
158   rra
159 .ok1A:
160   ld    (WinSys.printx),a
161   jr    PrintStrZ
162 .iscls:
163   cp    #0C
164   jr    nz,.doNL
165   push  hl,bc
166   call  ClearWin
167   pop   bc,hl
168   jr    PrintStrZ
169 .doNL:
170   call  printstr__doNL_routine
171   jr    PrintStrZ
172 @printstr__doNL_routine:
173   ex    de,hl
174   ld    hl,WinSys.printxy
175   ld    (hl),0
176   inc   hl
177   inc   (hl)
178   ld    a,(WinSys.wsize+1)
179   cp    (hl)
180   ex    de,hl
181   jr    z,.doNL_noq
182   jr    nc,.q0
183 .doNL_noq:
184   dec   a
185   ld    (de),a
186   push  hl
187   call  ScrollUp
188   pop   hl
189 .q0:
190   ret
193 PrintNL:
194   push  bc,de,hl
195   call  printstr__doNL_routine
196   pop   hl,de,bc
197   ret
200 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
201 ;; in:
202 ;;   a: char code (32-255)
203 ;; out:
204 ;;   af', af: destroyed
205 PrintChar:
206   cp    #1A
207   jp    c,PrintNL
208   cp    32
209   ret   c
210   push  bc,de,hl
211   ld    e,a
212   ex    af,af'
213   xor   a
214   ld    hl,WinSys.attr
215   bit   7,(hl)
216   jr    z,.noCPL
217   ld    a,#2F   ; cpl
218 .noCPL:
219   ld    (.pccpl),a
220   ; get width
221   ld    d,0
222   ld    hl,(WinFont.chars)
223   add   hl,de
224   ld    a,(hl)  ; a: char width
225   or    a
226   jp    z,.quit
227   ; test for scroll
228   ; calc char pos if the last pixel
229   ld    b,a
230   ld    hl,WinSys.printxy
231   ld    de,WinSys.wsize
232   ld    a,(de)
233   cp    32
234   ld    a,(hl)
235   inc   hl
236   jr    nz,.testx
237   ; right edge just beyond the right screen edge; pissfuckshit!
238   inc   de
239   add   a,b
240   jr    nc,.testy
241   jr    z,.testy
242   jr    .nexty
243 .testx:
244   add   a,b
245   dec   a
246   and   #F8
247   rrca
248   rrca
249   rrca
250   ld    c,a
251   ld    a,(de)
252   inc   de
253   cp    c
254   jr    nc,.testy
255 .nexty:
256   dec   hl
257   ld    (hl),0
258   inc   hl
259   inc   (hl)
260 .testy:
261   ld    a,(de)
262   cp    (hl)
263   jr    z,.do_scroll
264   jr    nc,.do_print
265 .do_scroll:
266   dec   a
267   ld    (hl),a
268   dec   hl
269   ld    (hl),0
270   push  bc
271   call  ScrollUp
272   pop   bc
273 .do_print:
274   push  bc         ; b: char width
275   ; calc scr. addr
276   ld    de,(WinSys.printxy)
277   ld    hl,WinSys.orig
278   ld    a,(hl)
279   inc   hl
280   add   a,a
281   add   a,a
282   add   a,a
283   add   a,e
284   ld    e,a
285   ld    a,(hl)
286   add   a,d
287   add   a,a
288   add   a,a
289   add   a,a
290   ld    d,a
291   ;call WinMisc.scrCalcAddrDE_HL
292   ;ld    a,d
293   and   a
294   rra
295   scf
296   rra
297   and   a
298   rra
299   xor   d
300   and   #F8
301   xor   d
302   ld    h,a
303   ld    a,e
304   rlca
305   rlca
306   rlca
307   xor   d
308   and   #C7
309   xor   d
310   rlca
311   rlca
312   ld    l,a
313   ld    a,e
314   and   #07
315   ;
316   ld    (.shiftc+1),a
317   push  hl,af
318   ; build mask
319   ld    hl,#00FF
320   ld    a,b
321   or    a
322   jr    z,.bmok
323 .bm_loop:
324   scf
325   rr    h
326   djnz  .bm_loop
327 .bmok:
328   ld    a,h
329   ld    (.mask_chr+1),a
330   cpl
331   ld    h,a
332   ; shift mask
333   pop   af
334   or    a
335   jr    z,.nomshift
336   ld    b,a
337 .mshift_loop:
338   scf
339   rr    h
340   rr    l
341   djnz  .mshift_loop
342 .nomshift:
343   ld    (.mask+1),hl
344   ; calc char addr
345   ex    af,af'
346   ld    l,a
347   ld    h,0
348   add   hl,hl
349   add   hl,hl
350   add   hl,hl
351   ld    de,(WinFont.chars)
352   add   hl,de
353   pop   de
354   ; now: hl: char addr; de: screen addr
355   push  de
356   ex    de,hl
357   ; now: de: char addr; hl: screen addr
358   ld    b,8
359 .loop:
360   push  bc
361   ld    a,(de)
362   inc   de
363 .pccpl:
364   cpl
365 .mask_chr:
366   and   #00
367   ld    c,a
368 .shiftc:
369   ld    a,0
370   or    a
371   ld    b,a
372   ld    a,c
373   ld    c,0
374   jr    z,.shiftend
375 .shift:
376   rra
377   rr    c
378   djnz  .shift
379 .shiftend:
380   push  de
381 .mask:
382   ld    de,0
383   ld    b,a
384   ld    a,(hl)
385   and   d
386   or    b
387   ld    (hl),a
388   inc   hl
389   ld    a,(hl)
390   and   e
391   or    c
392   ld    (hl),a
393   dec   hl
394   inc   h
395   pop   de
396   pop   bc
397   djnz  .loop
398   ; set attr
399   pop   hl
400   ld    a,h
401   rrca
402   rrca
403   rrca
404   and   #03
405   or    #58
406   ld    h,a
407   ld    a,(WinSys.attr)
408   and   #7F
409   ld    (hl),a
410   inc   hl
411   ld    c,a
412   ld    a,(.mask+1)
413   cp    #ff
414   jr    z,.noattr
415   ld    (hl),c
416 .noattr:
417   ; move to the next x pos
418   pop   af
419   ld    hl,WinSys.printxy
420   add   a,(hl)
421   jr    nc,.nq_0
422   inc   hl
423   inc   (hl)
424   dec   hl
425   xor   a
426 .nq_0:
427   ld    (hl),a
428 .quit:
429   pop   hl,de,bc
430   ret
433 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
434 ;; scroll window contents (up)
435 ;; out:
436 ;;   af,bc,de,hl: destroyed
437 ScrollUp:
438   ld    hl,WinSys.orig
439   ld    e,(hl)
440   inc   hl
441   ld    a,(hl)
442   and   #18
443   or    #40
444   ld    d,a
445   ld    a,(hl)
446   inc   hl
447   rrca
448   rrca
449   rrca
450   and   #E0
451   or    e
452   ld    e,a
453   ld    c,(hl)
454   inc   hl
455   ld    b,(hl)
456   dec   b
457 .lloop:
458   ; now: de: dest; c: width; b: height
459   call  DownCharDEHL
460   ; now: hl: src; de: dest; c: width; b: height
461   push  hl,bc,de
462   ld    b,8
463 .zloop:
464   push  bc,de,hl
465   ld    b,0
466   ldir
467   pop   hl,de,bc
468   inc   h
469   inc   d
470   djnz  .zloop
471   pop   hl
472   call  Scr2AttrHLDE
473   dec   de
474   ld    bc,32
475   add   hl,bc
476   pop   bc
477   push  bc
478   ld    b,0
479   ldir
480   pop   bc
481   pop   de
482   djnz  .lloop
483   ; clear last line
484   dec   c
485   push  bc,de
486   ld    b,8
487 .czloop:
488   ld    l,e
489   ld    h,d
490   inc   de
491   push  hl,bc
492   ld    b,0
493   ld    (hl),b
494   ldir
495   pop   bc,de
496   inc   d
497   djnz  .czloop
498   pop   hl
499   call  Scr2AttrHLDE
500   ld    a,(WinSys.attr)
501   and   #7F
502   ld    (hl),a
503   pop   bc
504   ld    b,0
505   ldir
506   ret
509 DownCharDEHL:
510   ld    a,e
511   add   a,#20
512   ld    l,a
513   ld    a,d
514   jr    nc,.noadd:
515   add   a,#08
516 .noadd:
517   ld    h,a
518   ret
521 Scr2AttrHLDE:
522   ld    a,h
523   rrca
524   rrca
525   rrca
526   and   #03
527   or    #58
528   ld    h,a
529   ld    de,hl
530   inc   de
531   ret
534 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
535 ;; clear window area
536 ;; out:
537 ;;   af,bc,de,hl: destroyed
538 ClearWin:
539   ld    hl,0
540   ld    (WinSys.printxy),hl
541   ld    de,(WinSys.orig)
542   ;call WinMisc.scrAddr8DE_HL
543   ld    a,d
544   and   #18
545   or    #40
546   ld    h,a
547   ld    a,d
548   rrca
549   rrca
550   rrca
551   and   #E0
552   or    e
553   ld    l,a
554   ;
555   ld    bc,(WinSys.wsize)
556   dec   c
557 .lineloop:
558   push  bc
559   ld    b,8
560   push  hl
561   xor   a
562 .zloop:
563   push  bc
564   push  hl
565   ld    e,l
566   ld    d,h
567   inc   de
568   ld    (hl),a
569   ld    b,a
570   ldir
571   pop   hl
572   inc   h
573   pop   bc
574   djnz  .zloop
575   pop   hl
576   push  hl
577   ld    b,a
578   call  Scr2AttrHLDE
579   ld    a,(WinSys.attr)
580   ld    (hl),a
581   ldir
582   pop   de
583   call  DownCharDEHL
584   pop   bc
585   djnz  .lineloop
586   ret
588   endmodule