4 ; Low-level graphics and mouse/keyboard handling
6 ; © 1994-1998 Straylight
9 ;----- Licensing note -------------------------------------------------------
11 ; This file is part of Straylight's Steel library.
13 ; Steel is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
18 ; Steel is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ; GNU General Public License for more details.
23 ; You should have received a copy of the GNU General Public License
24 ; along with Steel. If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 ;----- Standard stuff -------------------------------------------------------
32 AREA |C$$Code|,CODE,READONLY
34 ;----- VDU and character output ---------------------------------------------
38 ; On entry: a1 == a character to output
41 bbc_vdu SWI XOS_WriteC
47 ; On entry: a1 == halfword to output
50 bbc_vduw SWI XOS_WriteC
58 ; On entry: APCS args contain bytes to output
60 bbc__vduqTable DCB 1,2,1,1,1,1,1,1
68 STMFD sp!,{a2-a4} ;Stack extra args
69 ADR a2,bbc__vduqTable ;Point to the table
70 CMP a1,#' ' ;Is the char a control char?
71 MOVGE a2,#1 ;Yes -- only one in the queue
72 LDRLTB a2,[a2,a1] ;No -- load queue length
73 MOV a3,sp ;Point to queue on the stack
75 00bbc_vduq SWI XOS_WriteC ;Write the character out
76 ADDVS sp,sp,#12 ;If it failed, reclaim stack
77 MOVVSS pc,lr ;And quit right this second
78 SUBS a2,a2,#1 ;Decrement the byte counter
79 LDRGT a1,[a3],#4 ;If more, get another byte
80 BGT %00bbc_vduq ;And print that one too
82 ADD sp,sp,#12 ;Bump the stack back again
83 MOV a1,#0 ;No error returned
84 MOVS pc,lr ;Return to the caller
86 ; --- bbc_stringprint ---
88 ; On entry: a1 == pointer to a NULL-terminated string
90 EXPORT bbc_stringprint
91 bbc_stringprint SWI XOS_Write0
100 bbc_cls SWI XOS_WriteI+12
106 ; On entry: a1 == text colour to set
109 bbc_colour SWI XOS_WriteI+17
117 ; On exit: a1 == x coord of text cursor
128 ; On exit: a1 == y coord of text cursor
138 ; On entry: a1 == x coordinate to move to
139 ; a2 == y coordinate to move to
142 bbc_tab SWI XOS_WriteI+31
149 ;----- Graphics output ------------------------------------------------------
153 ; On entry: a1 == plot code number
154 ; a2 == x coordinate to plot at
155 ; a3 == y coordinate to plot at
158 bbc_plot SWI XOS_Plot
164 ; On entry: a1 == new mode number to set
167 bbc_mode SWI XOS_WriteI+22
174 ; On entry: a1 == x coordinate to move to
175 ; a2 == y coordinate to move to
187 ; On entry: a1 == x offset to move to
188 ; a2 == y offset to move to
200 ; On entry: a1 == x coordinate to draw to
201 ; a2 == y coordinate to draw to
213 ; On entry: a1 == x offset to draw to
214 ; a2 == y offset to draw to
224 ; --- bbc_rectangle ---
226 ; On entry: a1 == bottom left x coordinate
227 ; a2 == bottom left y coordinate
228 ; a3 == rectangle width
229 ; a4 == rectangle height
232 bbc_rectangle MOV ip,a3 ;Look after rectangle width
256 ; --- bbc_rectanglefill ---
258 ; On entry: a1 == bottom left x coordinate
259 ; a2 == bottom left y coordinate
260 ; a3 == rectangle width
261 ; a4 == rectangle height
263 EXPORT bbc_rectanglefill
270 MOVVC a1,#&61 ;Rectangle plot relative
279 ; On entry: a1 == x coordinate of centre
280 ; a2 == y coordinate of centre
281 ; a3 == radius of circle
296 ; --- bbc_circlefill ---
298 ; On entry: a1 == x coordinate of centre
299 ; a2 == y coordinate of centre
300 ; a3 == radius of circle
302 EXPORT bbc_circlefill
303 bbc_circlefill MOV a4,a3
317 ; On entry: a1 == x coordinate to move origin to
318 ; a2 == x coordinate to move origin to
321 bbc_origin SWI XOS_WriteI+29
332 ; --- bbc_gwindow ---
334 ; On entry: a1 == bottom left x coord
335 ; a2 == bottom left y coord
336 ; a3 == top right x coord
337 ; a4 == top right y coord
340 bbc_gwindow SWI XOS_WriteI+24
364 bbc_clg SWI XOS_WriteI+16
370 ; On entry: a1 == x coordinate to fill from
371 ; a2 == y coordinate to fill from
373 ; WARNING: this call uses the OS flood-fill, which is (or at least used to
374 ; be) very badly broken. Use with care, or crash horribly. We may change
375 ; to use our own flood fill algorithm some day, but don't hold your breath.
387 ; On entry: a1 == gcol action
391 bbc_gcol SWI XOS_WriteI+18
400 ; On entry: a1 == tint action (what colour to set)
404 bbc_tint SWI XOS_WriteI+23 ;1
410 SWIVC XOS_WriteI+0 ;4
411 SWIVC XOS_WriteI+0 ;5
412 SWIVC XOS_WriteI+0 ;6
413 SWIVC XOS_WriteI+0 ;7
414 SWIVC XOS_WriteI+0 ;8
415 SWIVC XOS_WriteI+0 ;9
416 SWIVC XOS_WriteI+0 ;10
420 ; --- bbc_palette ---
422 ; On entry: a1 == logical colour to remap
423 ; a2 == physical colour to assign
424 ; a3 == red level to assign
425 ; a4 == green level to assign
426 ; [sp] == blue level to assign
429 bbc_palette SWI XOS_WriteI+19
444 ; On entry: a1 == x coordinate of point to read
445 ; a2 == y coordinate of point to read
446 ; On exit; a1 == logical colour at the point, or &FF if not on-screen
448 ; NOTE: The RISC_OSLib version is utterly buggered. For no known reason,
449 ; the fools decided to pass parameters in wholewords rather than OS_Word's
450 ; own inimitable halfwords, meaning that RISC_OSLib's bbc_point invariably
451 ; returns 0. We side-step the entire issue by using OS_ReadPoint instead.
463 ; On entry: a1 == variable number to read
464 ; On exit: a1 == variable value read
467 bbc_vduvar MOV a2,#-1 ;Terminator for input array
468 STMFD sp!,{a1-a3} ;Store on stack, with output
469 MOV a1,sp ;Point to the input array
470 ADD a2,a1,#8 ;Point to output word
471 SWI XOS_ReadVduVariables ;Read the variable's value
472 ADD sp,sp,#8 ;Point sp at the value
473 LDMIA sp!,{a1} ;Read the value
476 ; --- bbc_vduvars ---
478 ; On entry: a1 == pointer to input array
479 ; a2 == pointer to output array
482 bbc_vduvars SWI XOS_ReadVduVariables
486 ; --- bbc_modevar ---
488 ; On entry: a1 == mode number to read variable for
489 ; a2 == variable number
490 ; On exit: a1 == variable value
493 bbc_modevar SWI XOS_ReadModeVariable
497 ;----- Keyboard handling ----------------------------------------------------
502 ; On exit: a1 == key code read, bit 8 set if escape condition
505 bbc_get SWI XOS_ReadC
511 ; On entry: a1 == time to wait, or -ve inkey number
514 bbc_inkey MOV a3,a1,LSR #8
526 ; On entry: a1 == new text cursor mode
529 bbc_cursor SWI XOS_WriteI+23 ;1
530 SWIVC XOS_WriteI+1 ;2
532 SWIVC XOS_WriteI+0 ;4
533 SWIVC XOS_WriteI+0 ;5
534 SWIVC XOS_WriteI+0 ;6
535 SWIVC XOS_WriteI+0 ;7
536 SWIVC XOS_WriteI+0 ;8
537 SWIVC XOS_WriteI+0 ;9
538 SWIVC XOS_WriteI+0 ;10
542 ;----- Mouse handling -------------------------------------------------------
546 ; On entry: a1 == where to put x coordinate
547 ; a2 == where to put y coordinate
548 ; a3 == where to put button status
549 ; a4 == where to put time of click
552 bbc_mouse STMFD sp!,{v1-v4,lr}
558 LDMVSFD sp!,{v1-v4,pc}^
568 LDMFD sp!,{v1-v4,pc}^
570 ; --- bbc_mouserect ---
572 ; On entry: a1 == mouse rectangle bottom left x coord
573 ; a2 == mouse rectangle bottom left y coord
574 ; a3 == mouse rectangle top right x coord
575 ; a4 == mouse rectangle top right y coord
578 bbc_mouserect SUB sp,sp,#12
604 ;----- Strangeness ----------------------------------------------------------
608 ; NOTE: Since I don't have a clue about what the RISC_OSLib version's trying
609 ; to do, although at a guess it's utterly wrong. I'll just do it properly.
611 ; On entry: a1 == reason code for OS_Byte 128
612 ; On exit: a1 == output of OS_Byte 128
615 bbc_adval AND a2,a1,#&FF
619 ORRVC a1,a2,a3,LSL #8
622 ;----- Messing about with sound ---------------------------------------------
624 ; --- bbc_getbeat ---
627 ; On exit: a1 == current beat value
630 bbc_getbeat MOV a1,#0
634 ; --- bbc_getbeats ---
637 ; On exit: a1 == previous bar length
640 bbc_getbeats MOV a1,#-1
644 ; --- bbc_gettempo ---
647 ; On exit: a1 == tempo for beat counter
650 bbc_gettempo MOV a1,#0
654 ; --- bbc_setbeats ---
656 ; On entry: a1 == new bar length
659 bbc_setbeats SWI XSound_QBeat
663 ; --- bbc_settempo ---
665 ; On entry: a1 == new tempo for beat counter
668 bbc_settempo SWI XSound_QTempo
674 ; On entry: a1 == channel number
675 ; a2 == amplitude of noise to make
676 ; a3 == pitch to make the noise
677 ; a4 == duration of noise
678 ; [sp] == time to make the noise, or -2 for `right now'
683 LDR ip,[sp] ;Get the time to make noise
684 CMP ip,#-2 ;Do we make noises right now?
685 BEQ %00bbc_sound ;Yes -- deal with that case
687 ORR a4,a3,a4,LSL #16 ;Pack the arguments up
689 MOV a1,ip ;Get the time to schedule
690 MOV a2,#0 ;Use Sound_ControlPacked
691 SWI XSound_QSchedule ;Schedule the noise nicely
695 00bbc_sound SWI XSound_Control ;Just make a noise now
699 ; --- bbc_soundoff ---
704 bbc_soundoff MOV a1,#1
709 ; --- bbc_soundon ---
714 bbc_soundon MOV a1,#2
721 ; On entry: a1 == channel to set position of
722 ; a2 == new stereo position of channel
725 bbc_stereo SWI XSound_Stereo
731 ; On entry: a1 == number of voices to set
744 ;----- That's all, folks ----------------------------------------------------