Subversion Repositories Spectranet

[/] [trunk/] [test/] [test_output.asm] - Blame information for rev 117

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 117 winston
;The MIT License
2
;
3
;Copyright (c) 2008 Dylan Smith
4
;
5
;Permission is hereby granted, free of charge, to any person obtaining a copy
6
;of this software and associated documentation files (the "Software"), to deal
7
;in the Software without restriction, including without limitation the rights
8
;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
;copies of the Software, and to permit persons to whom the Software is
10
;furnished to do so, subject to the following conditions:
11
;
12
;The above copyright notice and this permission notice shall be included in
13
;all copies or substantial portions of the Software.
14
;
15
;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
;THE SOFTWARE.
22
 
23
; User interface output routines
24
; This is mostly about putting characters on the screen, and clearing the
25
; screen to the Spectranet UI colours. It doesn't depend on the ZX ROM.
26
; The print routine prints 42 columns wide.
27
 
28
;--------------------------------------------------------------------------
29
; F_putc_5by8 / F_putc_5by8_nopage
30
; Print characters 42 columns per line.
31
; The routine depends on a character set (in ui_charset.asm) and a lookup
32
; table (in ui_lookup.asm).
33
; Paramters: A = ASCII character to print.
34
F_putc_5by8
35
      push hl
36
      push bc
37
      push de
38
      cp '\n'     ; carriage return?
39
      jr z, .nextrow
40
 
41
      ; find the address of the character in the bitmap table
42
      sub 32      ; space = offset 0
43
      ld hl, 0
44
      ld l, a
45
 
46
      ; multiply by 8 to get the byte offset
47
      add hl, hl
48
      add hl, hl
49
      add hl, hl
50
 
51
      ; add the offset
52
      ld bc, char_space
53
      add hl, bc
54
 
55
      ; Now find the address in the frame buffer to be written.
56
      ex de, hl
57
      ld hl, col_lookup
58
      ld a, (v_column)
59
      ld b, a
60
      add a, l
61
      ld l, a        ; hl = pointer to byte in lookup table
62
      ld a, (hl)     ; a = lookup table value
63
      ld hl, (v_row) ; hl = framebuffer pointer for start of row
64
      add l
65
      ld l, a        ; hl = frame buffer address
66
 
67
; de contains the address of the char bitmap
68
; hl contains address in the frame buffer
69
.paintchar
70
      ld a, b           ; retrieve column
71
      and 3             ; find out how much we need to rotate
72
      jr z, .norotate   ; no need to rotate, character starts at MSB
73
      rla               ; multipy by 2
74
      ld (v_pr_wkspc), a   ; save A
75
      ld b, 8           ; byte copy count for outer loop
76
.fbwriterotated
77
      push bc           ; save outer loop count
78
      ld a, (v_pr_wkspc)
79
      ld b, a           ; set up rotate loop count
80
      ld a, (de)        ; get character bitmap
81
      ld c, a           ; C contains rightmost fragment of bitmap
82
      xor a             ; set a=0 to accept lefmost fragment of bitmap
83
.rotloop
84
      rl c
85
      rla               ; suck out leftmost bit from the carry flag
86
      djnz .rotloop
87
.writerotated
88
      or (hl)           ; merge with existing character
89
      ld (hl), a
90
      ld a, c
91
      cp 0
92
      jr z, .writerotated.skip   ; nothing to do
93
      inc l             ; next char cell
94
      or (hl)
95
      ld (hl), a
96
      dec l             ; restore l
97
.writerotated.skip
98
      inc h             ; next line
99
      inc de            ; next line of character bitmap
100
      pop bc            ; retrieve outer loop count
101
      djnz .fbwriterotated
102
.nextchar
103
      ld a, (v_column)
104
      inc a
105
      cp 42
106
      jr nz, .nextchar.done
107
.nextrow
108
      ld a, (v_rowcount) ; check the row counter
109
      cp 23             ; 24th line?
110
      jr nz, .noscroll
111
      call F_jumpscroll
112
      ld a, 16
113
      ld (v_rowcount), a
114
      ld hl, 0x5000     ; address of first row of bottom 1/3rd
115
      jr .nextchar.saverow ; save row addr and complete
116
.noscroll
117
      inc a
118
      ld (v_rowcount), a
119
      ld hl, (v_row)    ; advance framebuffer pointer to next character row
120
      ld a, l
121
      add 32
122
      jr c, .nextthird
123
      ld l, a
124
      jr .nextchar.saverow
125
.nextthird
126
      ld l, 0
127
      ld a, h
128
      add 8
129
      ld h, a
130
.nextchar.saverow
131
      ld (v_row), hl
132
      xor a             ; a = 0
133
.nextchar.done
134
      ld (v_column), a
135
 
136
      pop de
137
      pop bc
138
      pop hl
139
      ret
140
 
141
.norotate
142
      ld b, 8
143
.norotate.loop
144
      ld a, (de)        ; move bitmap into the frame buffer
145
      ld (hl), a
146
      inc de            ; next line of bitmap
147
      inc h             ; next line of frame buffer
148
      djnz .norotate.loop
149
      jr .nextchar
150
 
151
;--------------------------------------------------------------------------
152
; F_jumpscroll:
153
; a simple 'jump scroll' which scrolls the screen by 1/3rd. Simpler
154
; than scrolling one line.
155
F_jumpscroll
156
        push hl
157
        push de
158
        push bc
159
        ld hl, 0x4800   ; start of 2nd 1/3rd of screen
160
        ld de, 0x4000   ; first third
161
        ld bc, 0x1000   ; copy 2/3rds of the screen up by 1/3rd
162
        ldir
163
        ld hl, 0x5000   ; clear out last 2k
164
        ld de, 0x5001
165
        ld bc, 0x07FF
166
        ld (hl), 0
167
        ldir
168
        pop bc
169
        pop de
170
        pop hl
171
        ret
172
 
173
;-------------------------------------------------------------------------
174
; F_erasechar
175
; Removes the character at the current 5by8 character position.
176
; No parameters.
177
F_erasechar
178
        ; Find the address in the frame buffer.
179
        ld hl, col_lookup
180
        ld a, (v_column)
181
        ld b, a
182
        add a, l
183
        ld l, a         ; hl = pointer to byte in lookup table
184
        ld a, (hl)      ; a = lookup table value
185
        ld hl, (v_row)  ; hl = framebuffer pointer for start of row
186
        add l
187
        ld l, a         ; hl = frame buffer address
188
        ld a, b         ; retrieve column
189
        and 3           ; find out how much rotation is needed
190
        jr z, .norotate ; no need to do any at all
191
 
192
        rla             ; multiply by 2
193
        ld b, a         ; set loop count
194
        ld a, 0xFC      ; binary 11111100 - mask with no rotation
195
 
196
        ; now create two masks - one for the left byte, and one for the
197
        ; right byte.
198
        ld c, 0         ; c will contain left mask
199
.maskloop
200
        rla
201
        rl c
202
        djnz .maskloop
203
.rotated
204
        cpl             ; turn it into the proper mask value
205
        ld (v_pr_wkspc), a      ; save right byte mask
206
        ld b, 8         ; 8 bytes high
207
.rotated_loop
208
        inc l           ; right hand byte
209
        and (hl)        ; make new value
210
        ld (hl), a      ; write it back
211
        ld a, c         ; get left mask
212
        cpl
213
        dec l           ; point at left byte
214
        and (hl)
215
        ld (hl), a      ; write it back
216
        inc h           ; next line in frame buffer
217
        ld a, (v_pr_wkspc)      ; retrieve right byte mask
218
        djnz .rotated_loop
219
        ret             ; done
220
 
221
.norotate
222
        ld b, 8         ; 8 bytes high
223
.norotate_loop
224
        ld a, 0x03      ; mask out left 6 bits
225
        and (hl)        ; mask out character cell at current position
226
        ld (hl), a      ; write back to frame buffer
227
        inc h
228
        djnz .norotate_loop
229
        ret             ; done
230
 
231
;--------------------------------------------------------------------------
232
; F_backspace: Perform a backspace (move current character position 1
233
; back and delete the right most character).
234
F_backspace
235
        ld a, (v_column)
236
        and a           ; Are we at column 0?
237
        ret z           ; nothing more to do (possible TODO - go back a line)
238
        dec a           ; move column pointer one space back
239
        ld (v_column), a ; and store it
240
        jp F_erasechar  ; then erase the character that's there.
241
 
242
;--------------------------------------------------------------------------
243
; F_clear: Clears the screen to spectranet UI colours.
244
F_clear
245
        ld hl, 16384
246
        ld de, 16385
247
        ld bc, 6144
248
        ld (hl), 0
249
        ldir
250
        ld (hl), 56     ; attribute for white
251
        ld bc, 767
252
        ldir
253
        xor a
254
        ld (v_column), a
255
        ld (v_rowcount), a
256
        ld hl, 16384
257
        ld (v_row), hl
258
        ret
259
 
260
;--------------------------------------------------------------------------
261
; F_print: Prints a null terminated string.
262
; Parameters: HL = pointer to string
263
F_print
264
.loop
265
        ld a, (hl)
266
        and a                   ; NULL?
267
        jr z, .done
268
        call F_putc_5by8        ; print it
269
        inc hl
270
        jr .loop
271
.done
272
        ret
273