; ; bbc.s ; ; Low-level graphics and mouse/keyboard handling ; ; © 1994-1998 Straylight ; ;----- Licensing note ------------------------------------------------------- ; ; This file is part of Straylight's Steel library. ; ; Steel is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2, or (at your option) ; any later version. ; ; Steel is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with Steel. If not, write to the Free Software Foundation, ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ;----- Standard stuff ------------------------------------------------------- GET libs:header GET libs:swis AREA |C$$Code|,CODE,READONLY ;----- VDU and character output --------------------------------------------- ; --- bbc_vdu --- ; ; On entry: a1 == a character to output EXPORT bbc_vdu bbc_vdu SWI XOS_WriteC MOVVC a1,#0 MOVS pc,lr ; --- bbc_vduw --- ; ; On entry: a1 == halfword to output EXPORT bbc_vduw bbc_vduw SWI XOS_WriteC MOVVC a1,a1,LSR #8 SWIVC XOS_WriteC MOVVC a1,#0 MOVS pc,lr ; --- bbc_vduq --- ; ; On entry: APCS args contain bytes to output bbc__vduqTable DCB 1,2,1,1,1,1,1,1 DCB 1,1,1,1,1,1,1,1 DCB 1,2,3,6,1,1,2,10 DCB 9,6,1,1,5,5,1,3 EXPORT bbc_vduq bbc_vduq ROUT STMFD sp!,{a2-a4} ;Stack extra args ADR a2,bbc__vduqTable ;Point to the table CMP a1,#' ' ;Is the char a control char? MOVGE a2,#1 ;Yes -- only one in the queue LDRLTB a2,[a2,a1] ;No -- load queue length MOV a3,sp ;Point to queue on the stack 00bbc_vduq SWI XOS_WriteC ;Write the character out ADDVS sp,sp,#12 ;If it failed, reclaim stack MOVVSS pc,lr ;And quit right this second SUBS a2,a2,#1 ;Decrement the byte counter LDRGT a1,[a3],#4 ;If more, get another byte BGT %00bbc_vduq ;And print that one too ADD sp,sp,#12 ;Bump the stack back again MOV a1,#0 ;No error returned MOVS pc,lr ;Return to the caller ; --- bbc_stringprint --- ; ; On entry: a1 == pointer to a NULL-terminated string EXPORT bbc_stringprint bbc_stringprint SWI XOS_Write0 MOVVC a1,#0 MOVS pc,lr ; --- bbc_cls --- ; ; On entry: -- EXPORT bbc_cls bbc_cls SWI XOS_WriteI+12 MOVVC a1,#0 MOVS pc,lr ; --- bbc_colour --- ; ; On entry: a1 == text colour to set EXPORT bbc_colour bbc_colour SWI XOS_WriteI+17 SWIVC XOS_WriteC MOVVC a1,#0 MOVS pc,lr ; --- bbc_pos --- ; ; On entry: -- ; On exit: a1 == x coord of text cursor EXPORT bbc_pos bbc_pos MOV a1,#&86 SWI XOS_Byte MOV a1,a2 MOVS pc,lr ; --- bbc_vpos --- ; ; On entry: -- ; On exit: a1 == y coord of text cursor EXPORT bbc_vpos bbc_vpos MOV a1,#&86 SWI XOS_Byte MOV a1,a3 MOVS pc,lr ; --- bbc_tab --- ; ; On entry: a1 == x coordinate to move to ; a2 == y coordinate to move to EXPORT bbc_tab bbc_tab SWI XOS_WriteI+31 SWIVC XOS_WriteC MOVVC a1,a2 SWIVC XOS_WriteC MOVVC a1,#0 MOVS pc,lr ;----- Graphics output ------------------------------------------------------ ; --- bbc_plot --- ; ; On entry: a1 == plot code number ; a2 == x coordinate to plot at ; a3 == y coordinate to plot at EXPORT bbc_plot bbc_plot SWI XOS_Plot MOVVC a1,#0 MOVS pc,lr ; --- bbc_mode --- ; ; On entry: a1 == new mode number to set EXPORT bbc_mode bbc_mode SWI XOS_WriteI+22 SWIVC XOS_WriteC MOVVC a1,#0 MOVS pc,lr ; --- bbc_move --- ; ; On entry: a1 == x coordinate to move to ; a2 == y coordinate to move to EXPORT bbc_move bbc_move MOV a3,a2 MOV a2,a1 MOV a1,#4 SWI XOS_Plot MOVVC a1,#0 MOVS pc,lr ; --- bbc_moveby --- ; ; On entry: a1 == x offset to move to ; a2 == y offset to move to EXPORT bbc_moveby bbc_moveby MOV a3,a2 MOV a2,a1 MOV a1,#0 SWI XOS_Plot MOVVC a1,#0 MOVS pc,lr ; --- bbc_draw --- ; ; On entry: a1 == x coordinate to draw to ; a2 == y coordinate to draw to EXPORT bbc_draw bbc_draw MOV a3,a2 MOV a2,a1 MOV a1,#5 SWI XOS_Plot MOVVC a1,#0 MOVS pc,lr ; --- bbc_drawby --- ; ; On entry: a1 == x offset to draw to ; a2 == y offset to draw to EXPORT bbc_drawby bbc_drawby MOV a3,a2 MOV a2,a1 MOV a1,#1 SWI XOS_Plot MOVVC a1,#0 MOVS pc,lr ; --- bbc_rectangle --- ; ; On entry: a1 == bottom left x coordinate ; a2 == bottom left y coordinate ; a3 == rectangle width ; a4 == rectangle height EXPORT bbc_rectangle bbc_rectangle MOV ip,a3 ;Look after rectangle width MOV a3,a2 MOV a2,a1 MOV a1,#4 SWI XOS_Plot MOVVC a1,#9 MOVVC a2,ip MOVVC a3,#0 SWIVC XOS_Plot MOVVC a1,#9 MOVVC a2,#0 MOVVC a3,a4 SWIVC XOS_Plot MOVVC a1,#9 RSBVC a2,ip,#0 MOVVC a3,#0 SWIVC XOS_Plot MOVVC a1,#9 MOVVC a2,#0 RSBVC a3,a4,#0 SWIVC XOS_Plot MOVVC a1,#0 MOVS pc,lr ; --- bbc_rectanglefill --- ; ; On entry: a1 == bottom left x coordinate ; a2 == bottom left y coordinate ; a3 == rectangle width ; a4 == rectangle height EXPORT bbc_rectanglefill bbc_rectanglefill MOV ip,a3 MOV a3,a2 MOV a2,a1 MOV a1,#4 SWI XOS_Plot MOVVC a1,#&61 ;Rectangle plot relative MOVVC a2,ip MOVVC a3,a4 SWIVC XOS_Plot MOVVC a1,#0 MOVS pc,lr ; --- bbc_circle --- ; ; On entry: a1 == x coordinate of centre ; a2 == y coordinate of centre ; a3 == radius of circle EXPORT bbc_circle bbc_circle MOV a4,a3 MOV a3,a2 MOV a2,a1 MOV a1,#4 SWI XOS_Plot MOVVC a1,#&91 MOVVC a2,a4 MOVVC a3,#0 SWIVC XOS_Plot MOVVC a1,#0 MOVS pc,lr ; --- bbc_circlefill --- ; ; On entry: a1 == x coordinate of centre ; a2 == y coordinate of centre ; a3 == radius of circle EXPORT bbc_circlefill bbc_circlefill MOV a4,a3 MOV a3,a2 MOV a2,a1 MOV a1,#4 SWI XOS_Plot MOVVC a1,#&99 MOVVC a2,a4 MOVVC a3,#0 SWIVC XOS_Plot MOVVC a1,#0 MOVS pc,lr ; --- bbc_origin --- ; ; On entry: a1 == x coordinate to move origin to ; a2 == x coordinate to move origin to EXPORT bbc_origin bbc_origin SWI XOS_WriteI+29 SWIVC XOS_WriteC MOVVC a1,a1,LSR #8 SWIVC XOS_WriteC MOVVC a1,a2 SWIVC XOS_WriteC MOVVC a1,a1,LSR #8 SWIVC XOS_WriteC MOVVC a1,#0 MOVS pc,lr ; --- bbc_gwindow --- ; ; On entry: a1 == bottom left x coord ; a2 == bottom left y coord ; a3 == top right x coord ; a4 == top right y coord EXPORT bbc_gwindow bbc_gwindow SWI XOS_WriteI+24 SWIVC XOS_WriteC MOVVC a1,a1,LSR #8 SWIVC XOS_WriteC MOVVC a1,a2 SWIVC XOS_WriteC MOVVC a1,a1,LSR #8 SWIVC XOS_WriteC MOVVC a1,a3 SWIVC XOS_WriteC MOVVC a1,a1,LSR #8 SWIVC XOS_WriteC MOVVC a1,a4 SWIVC XOS_WriteC MOVVC a1,a1,LSR #8 SWIVC XOS_WriteC MOVVC a1,#0 MOVS pc,lr ; --- bbc_clg --- ; ; On entry: -- EXPORT bbc_clg bbc_clg SWI XOS_WriteI+16 MOVVC a1,#0 MOVS pc,lr ; --- bbc_fill --- ; ; On entry: a1 == x coordinate to fill from ; a2 == y coordinate to fill from ; ; WARNING: this call uses the OS flood-fill, which is (or at least used to ; be) very badly broken. Use with care, or crash horribly. We may change ; to use our own flood fill algorithm some day, but don't hold your breath. EXPORT bbc_fill bbc_fill MOV a3,a2 MOV a2,a1 MOV a1,#&85 SWI XOS_Plot MOVVC a1,#0 MOVS pc,lr ; --- bbc_gcol --- ; ; On entry: a1 == gcol action ; a2 == gcol value EXPORT bbc_gcol bbc_gcol SWI XOS_WriteI+18 SWIVC XOS_WriteC MOVVC a1,a2 SWIVC XOS_WriteC MOVVC a1,#0 MOVS pc,lr ; --- bbc_tint --- ; ; On entry: a1 == tint action (what colour to set) ; a2 == tint value EXPORT bbc_tint bbc_tint SWI XOS_WriteI+23 ;1 ANDVC a1,a1,#&03 SWIVC XOS_WriteC ;2 MOVVC a1,a2,LSL #6 ANDVC a1,a1,#&C0 SWIVC XOS_WriteC ;3 SWIVC XOS_WriteI+0 ;4 SWIVC XOS_WriteI+0 ;5 SWIVC XOS_WriteI+0 ;6 SWIVC XOS_WriteI+0 ;7 SWIVC XOS_WriteI+0 ;8 SWIVC XOS_WriteI+0 ;9 SWIVC XOS_WriteI+0 ;10 MOVVC a1,#0 MOVS pc,lr ; --- bbc_palette --- ; ; On entry: a1 == logical colour to remap ; a2 == physical colour to assign ; a3 == red level to assign ; a4 == green level to assign ; [sp] == blue level to assign EXPORT bbc_palette bbc_palette SWI XOS_WriteI+19 SWIVC XOS_WriteC MOVVC a1,a2 SWIVC XOS_WriteC MOVVC a1,a3 SWIVC XOS_WriteC MOVVC a1,a4 SWIVC XOS_WriteC LDRVC a1,[sp] SWIVC XOS_WriteC MOVVC a1,#0 MOVS pc,lr ; --- bbc_point --- ; ; On entry: a1 == x coordinate of point to read ; a2 == y coordinate of point to read ; On exit; a1 == logical colour at the point, or &FF if not on-screen ; ; NOTE: The RISC_OSLib version is utterly buggered. For no known reason, ; the fools decided to pass parameters in wholewords rather than OS_Word's ; own inimitable halfwords, meaning that RISC_OSLib's bbc_point invariably ; returns 0. We side-step the entire issue by using OS_ReadPoint instead. EXPORT bbc_point bbc_point MOV ip,v1 SWI XOS_ReadPoint MOV v1,ip MOVVS a1,#&FF ANDVC a1,a3,#&FF MOVS pc,lr ; --- bbc_vduvar --- ; ; On entry: a1 == variable number to read ; On exit: a1 == variable value read EXPORT bbc_vduvar bbc_vduvar MOV a2,#-1 ;Terminator for input array STMFD sp!,{a1-a3} ;Store on stack, with output MOV a1,sp ;Point to the input array ADD a2,a1,#8 ;Point to output word SWI XOS_ReadVduVariables ;Read the variable's value ADD sp,sp,#8 ;Point sp at the value LDMIA sp!,{a1} ;Read the value MOVS pc,lr ; --- bbc_vduvars --- ; ; On entry: a1 == pointer to input array ; a2 == pointer to output array EXPORT bbc_vduvars bbc_vduvars SWI XOS_ReadVduVariables MOVVC a1,#0 MOVS pc,lr ; --- bbc_modevar --- ; ; On entry: a1 == mode number to read variable for ; a2 == variable number ; On exit: a1 == variable value EXPORT bbc_modevar bbc_modevar SWI XOS_ReadModeVariable MOV a1,a3 MOVS pc,lr ;----- Keyboard handling ---------------------------------------------------- ; --- bbc_get --- ; ; On entry: -- ; On exit: a1 == key code read, bit 8 set if escape condition EXPORT bbc_get bbc_get SWI XOS_ReadC ORRCS a1,a1,#&100 MOVS pc,lr ; --- bbc_inkey --- ; ; On entry: a1 == time to wait, or -ve inkey number EXPORT bbc_inkey bbc_inkey MOV a3,a1,LSR #8 AND a3,a3,#&FF AND a2,a1,#&FF MOV a1,#&81 SWI XOS_Byte CMP a3,#&FF MOVEQ a1,#-1 MOVNE a1,a2 MOVS pc,lr ; --- bbc_cursor --- ; ; On entry: a1 == new text cursor mode EXPORT bbc_cursor bbc_cursor SWI XOS_WriteI+23 ;1 SWIVC XOS_WriteI+1 ;2 SWIVC XOS_WriteC ;3 SWIVC XOS_WriteI+0 ;4 SWIVC XOS_WriteI+0 ;5 SWIVC XOS_WriteI+0 ;6 SWIVC XOS_WriteI+0 ;7 SWIVC XOS_WriteI+0 ;8 SWIVC XOS_WriteI+0 ;9 SWIVC XOS_WriteI+0 ;10 MOVVC a1,#0 MOVS pc,lr ;----- Mouse handling ------------------------------------------------------- ; --- bbc_mouse --- ; ; On entry: a1 == where to put x coordinate ; a2 == where to put y coordinate ; a3 == where to put button status ; a4 == where to put time of click EXPORT bbc_mouse bbc_mouse STMFD sp!,{v1-v4,lr} MOV v1,a1 MOV v2,a2 MOV v3,a3 MOV v4,a4 SWI XOS_Mouse LDMVSFD sp!,{v1-v4,pc}^ CMP v1,#0 STRNE a1,[v1] CMP v2,#0 STRNE a2,[v2] CMP v3,#0 STRNE a3,[v3] CMP v4,#0 STRNE a4,[v4] MOV a1,#0 LDMFD sp!,{v1-v4,pc}^ ; --- bbc_mouserect --- ; ; On entry: a1 == mouse rectangle bottom left x coord ; a2 == mouse rectangle bottom left y coord ; a3 == mouse rectangle top right x coord ; a4 == mouse rectangle top right y coord EXPORT bbc_mouserect bbc_mouserect SUB sp,sp,#12 MOV ip,#1 STRB ip,[sp,#0] MOV ip,a1 STRB ip,[sp,#1] MOV ip,a1,LSR #8 STRB ip,[sp,#2] MOV ip,a2 STRB ip,[sp,#3] MOV ip,a2,LSR #8 STRB ip,[sp,#4] MOV ip,a3 STRB ip,[sp,#5] MOV ip,a3,LSR #8 STRB ip,[sp,#6] MOV ip,a4 STRB ip,[sp,#7] MOV ip,a4,LSR #8 STRB ip,[sp,#8] MOV a1,#21 MOV a2,sp SWI XOS_Word ADD sp,sp,#12 MOVVC a1,#0 MOVS pc,lr ;----- Strangeness ---------------------------------------------------------- ; --- bbc_adval --- ; ; NOTE: Since I don't have a clue about what the RISC_OSLib version's trying ; to do, although at a guess it's utterly wrong. I'll just do it properly. ; ; On entry: a1 == reason code for OS_Byte 128 ; On exit: a1 == output of OS_Byte 128 EXPORT bbc_adval bbc_adval AND a2,a1,#&FF MOV a1,#&80 SWI XOS_Byte MOVVS a1,#&80000000 ORRVC a1,a2,a3,LSL #8 MOVS pc,lr ;----- Messing about with sound --------------------------------------------- ; --- bbc_getbeat --- ; ; On entry: -- ; On exit: a1 == current beat value EXPORT bbc_getbeat bbc_getbeat MOV a1,#0 SWI XSound_QBeat MOVS pc,lr ; --- bbc_getbeats --- ; ; On entry: -- ; On exit: a1 == previous bar length EXPORT bbc_getbeats bbc_getbeats MOV a1,#-1 SWI XSound_QBeat MOVS pc,lr ; --- bbc_gettempo --- ; ; On entry: -- ; On exit: a1 == tempo for beat counter EXPORT bbc_gettempo bbc_gettempo MOV a1,#0 SWI XSound_QTempo MOVS pc,lr ; --- bbc_setbeats --- ; ; On entry: a1 == new bar length EXPORT bbc_setbeats bbc_setbeats SWI XSound_QBeat MOVVC a1,#0 MOVS pc,lr ; --- bbc_settempo --- ; ; On entry: a1 == new tempo for beat counter EXPORT bbc_settempo bbc_settempo SWI XSound_QTempo MOVVC a1,#0 MOVS pc,lr ; --- bbc_sound --- ; ; On entry: a1 == channel number ; a2 == amplitude of noise to make ; a3 == pitch to make the noise ; a4 == duration of noise ; [sp] == time to make the noise, or -2 for `right now' EXPORT bbc_sound bbc_sound ROUT LDR ip,[sp] ;Get the time to make noise CMP ip,#-2 ;Do we make noises right now? BEQ %00bbc_sound ;Yes -- deal with that case ORR a4,a3,a4,LSL #16 ;Pack the arguments up ORR a3,a1,a2,LSL #16 MOV a1,ip ;Get the time to schedule MOV a2,#0 ;Use Sound_ControlPacked SWI XSound_QSchedule ;Schedule the noise nicely MOVVC a1,#0 MOVS pc,lr 00bbc_sound SWI XSound_Control ;Just make a noise now MOVVS a1,#0 MOVS pc,lr ; --- bbc_soundoff --- ; ; On entry: -- EXPORT bbc_soundoff bbc_soundoff MOV a1,#1 SWI XSound_Enable MOVVC a1,#0 MOVS pc,lr ; --- bbc_soundon --- ; ; On entry: -- EXPORT bbc_soundon bbc_soundon MOV a1,#2 SWI XSound_Enable MOVVC a1,#0 MOVS pc,lr ; --- bbc_stereo --- ; ; On entry: a1 == channel to set position of ; a2 == new stereo position of channel EXPORT bbc_stereo bbc_stereo SWI XSound_Stereo MOVVC a1,#0 MOVS pc,lr ; --- bbc_voices --- ; ; On entry: a1 == number of voices to set EXPORT bbc_voices bbc_voices MOV ip,v1 MOV a2,#0 MOV a3,#0 MOV a4,#0 MOV v1,#0 SWI XSound_Configure MOV v1,ip MOVVC a1,#0 MOVS pc,lr ;----- That's all, folks ---------------------------------------------------- END