; > Interface ; Interface to host system ; IO commands/functions/queries/etc ; Done, tested: ; CLS, CLG, COLOUR, MODE, =MODE, =POS, =VPOS, OSCLI, DRAW, MOVE, PLOT, GCOL, VDU ; =POINT, =VDU ; time=, time$=, =time, =time$ ; VDU Commands ; ============ ; CLS - Clear Text Window ; ======================= .cmdCLS CLRB SV_COUNT MOV #12,R0 JMP IO_WRCH ; CLG - Clear graphics window ; =========================== .cmdCLG MOV #16,R0 JMP IO_WRCH ; PLOT k,x,y - Send PLOT command ; ============================== .cmdPLOT jsr pc,EvalInteger ; Get PLOT command jsr pc,CheckComma ; Step past ',' br cmdPLOTetc ; Parse x,y ; DRAW x,y - Send DRAW command ; ============================ .cmdDRAW mov #5,r4 ; DRAW is PLOT 5 br cmdPLOTetc ; MOVE x,y - Send MOVE command ; ============================ .cmdMOVE mov #4,r4 ; MOVE is PLOT 4 .cmdPLOTetc mov r4,-(sp) ; Save command jsr pc,EvalInteger mov r4,-(sp) ; Save X coord jsr pc,CheckComma jsr pc,EvalInteger mov (sp)+,r3 ; R3=X, R4=Y mov (sp)+,r2 ; R0=command mov #25,r0 jsr pc,IO_WRCH ; PLOT mov r2,r0 jsr pc,IO_WRCH ; k mov r3,r0 jsr pc,IO_WRCH ; X low byte swab r0 jsr pc,IO_WRCH ; X high byte mov r4,r0 jsr pc,IO_WRCH ; Y low byte swab r0 jmp IO_WRCH ; Y high byte ; GCOL a,c - Set graphics colour ; ============================== .cmdGCOL jsr pc,EvalInteger mov r4,-(sp) jsr pc,EvalComma mov (sp)+,r3 ; r3=action, r4=colour mov #18,r0 jsr pc,IO_WRCH mov r3,r0 jsr pc,IO_WRCH mov r4,r0 jmp IO_WRCH ; COLOUR c - Set text colour ; ========================== .cmdCOLOUR jsr pc,EvalInteger mov #17,r0 jsr pc,IO_WRCH mov r4,r0 jmp IO_WRCH ; MODE m - Set screen mode ; ======================== .cmdMODE clrb SV_COUNT jsr pc,EvalInteger mov #22,r0 jsr pc,IO_WRCH mov r4,r0 jmp IO_WRCH ; VDU n[,|;[n]] - Send to VDU stream ; ================================== .cmdVDUcomma jsr pc,CheckComma2 ; Check with stepping forward .cmdVDU jsr pc,EvalInteger mov r4,r0 jsr pc,IO_WRCH jsr pc,SkipSpaces cmp r0,#13 beq cmdVDUexit inc r5 ; step past seperator mov #8,r1 cmp r0,#ASC"|" beq cmdOFFzero ; Send 8 zeros cmp r0,#&3B ; semicolon bne cmdVDUcomma ; Loop back for next value mov r4,r0 swab r0 jsr pc,IO_WRCH ; Send top byte br cmdVDU .cmdVDUexit rts pc ; OFF - turn cursor off ; ===================== .cmdOFF mov #0,r1 br cmdOFF1 ; ON - turn cursor on ; =================== .cmdOFFon mov #1,r1 .cmdOFF1 mov #23,r0 jsr pc,IO_WRCH mov #1,r0 jsr pc,IO_WRCH mov r1,r0 jsr pc,IO_WRCH mov #7,r1 .cmdOFFzero mov #0,r0 .cmdOFFlp jsr pc,IO_WRCH dec r1 bne cmdOFFlp rts pc ; Character Input Functions ; ========================= ; =GET$ - wait for character from input ; ===================================== .fnGETs JSR PC,IO_RDCH ; Wait for key .fnReadOneChar MOV #1,R3 ; R3=string length .fnReadChar MOV #&8000,R2 ; R2=string type MOV SV_STRING,R4 ; R4=>string buffer MOV R0,(R4) ; Put character into buffer RTS PC ; =INKEY$ time - wait specified time for character ; ================================================ .fnINKEYs JSR PC,EvalInteger ; Evaluate parameter MOV R4,R1 ; R1=parameter MOV #&81,R0 ; R0=INKEY JSR PC,IO_BYTE ; Read keypress BCC fnReadOneChar MOV #0,R3 BR fnReadChar ; =GET - wait for character from input ; nb, also =GET(port) ; ==================================== .fnGET JSR PC,IO_RDCH ; Wait for key MOV R0,R4 ; R4=keypress MOV #0,R3 ; R3=b16-b31=0 MOV #0,R2 ; R2=integer type RTS PC ; =INKEY time - wait specified time for character ; =============================================== .fnINKEY JSR PC,EvalInteger ; Evaluate parameter MOV R4,R1 ; R1=parameter MOV #&81,R0 ; R0=INKEY JSR PC,IO_BYTE ; Read keypress BCS fnINKEYnull MOV R0,R4 ; R4=keypress MOV #0,R3 ; R3=b16-b31=0 MOV #0,R2 ; R2=integer type RTS PC .fnINKEYnull MOV #&FFFF,R4 ; R4/3=-1 MOV #&FFFF,R3 MOV #0,R2 ; R2=integer type RTS PC ; =POS - read horizontal cursor position ; ====================================== .fnPOS mov #&86,r0 jsr pc,IO_BYTE mov r1,r4 bic #&FF00,r4 mov #0,r3 mov #0,r2 rts pc ; =VPOS - read vertical cursor position ; ===================================== .fnVPOS mov #&86,r0 jsr pc,IO_BYTE mov r2,r4 bic #&FF00,r4 mov #0,r3 mov #0,r2 rts pc ; =MODE - read current screen mode ; ================================ .fnMODE mov #&87,r0 jsr pc,IO_BYTE mov r1,r4 swab r4 bic #&FF00,r4 mov #0,r3 mov #0,r2 rts pc ; =POINT(x,y) - read colour at point ; ================================== .fnPOINT jsr pc,EvalInteger ; Get X parameter mov r4,-(sp) ; Save it jsr pc,EvalComma ; Step past ',', get Y parameter jsr pc,CheckClose ; Step past ')' mov r4,MOS_BUF+2 ; Put Y in control block mov (sp)+,MOS_BUF+0 ; Put X in control block adr MOS_BUF,r1 mov #9,r0 jsr pc,IO_WORD ; Call POINT routine movb MOS_BUF+4,r4 ; Get pixel value ; sign extend into r3 mov #0,r2 ; Type=Integer rts pc ; =VDU n - read VDU variable ; ========================== .fnVDU jsr pc,EvalInteger ; Get VDU variable number mov #160,r0 mov r4,r1 jsr pc,IO_BYTE ; Read VDU variable mov r1,r4 bic #&FF00,r4 ; r4=vdu variable mov #0,r3 ; r3=0000 mov #0,r2 ; Type=Integer rts pc ; File Commands ; ============= ; CLOSE#chn - Close channel ; ========================= .cmdCLOSE jsr pc,EvalHash ; Step past '#', get integer mov #0,r0 jmp IO_FIND ; BPUT#chn,byte - Write byte to channel ; ===================================== .cmdBPUT jsr pc,EvalHash ; Step past '#', get integer handle mov r4,-(sp) ; Save handle jsr pc,EvalComma ; Step past ',', get integer byte to write mov (sp)+,r1 ; Get handle to R1 mov r4,r0 ; Move byte to R0 jmp IO_BPUT ; Call MOS to write byte ; PTR#chn=val - Set file pointer ; ============================== .cmdPTR mov #1,r0 ; R0=1 for write PTR br cmdPTR1 ; EXT#chn=val - Set file extent ; ============================= .cmdEXT mov #3,r0 ; R0=3 for write EXT .cmdPTR1 mov r0,-(sp) ; Save function jsr pc,EvalHash ; Step past '#', get integer handle mov r4,-(sp) ; Save handle jsr pc,EvalEqual ; Step past '=', get integer pointer mov r4,(ARGS_ADDR+0) ; Store pointer in ARGS block mov r3,(ARGS_ADDR+2) mov (sp)+,r1 ; Get handle to R1 mov (sp)+,r0 ; Get function number adr ARGS_ADDR,r2 ; Point to ARGS block jmp IO_ARGS ; Call MOS to write PTR ; LOAD str$ - Load program ; ======================== ; Fetch CR-string parameter ; Call LoadProgram (finding TOP) ; Jump to Immediate mode .cmdLOAD JSR PC,EvalStringCR ; Get filename to R4 JSR PC,LoadProgram ; Load program, check TOP JMP Immediate ; Drop to immediate mode ; Load program named at R4 ; ------------------------ .LoadProgram MOV R4,FILE_NAME MOV SV_PAGE,FILE_LOAD MOV #&82,R0 JSR PC,IO_BYTE MOV R1,FILE_LOAD+2 MOV #0,FILE_EXEC ADR FILE_NAME,R1 MOV #255,R0 JSR PC,IO_FILE ; ; Check for loaded text and tokenise ; ; Check program consistancy and set TOP ; ------------------------------------- .FindTOP mov SV_PAGE,R1 ; Start at PAGE ; ; check program, find TOP ; rts pc ; SAVE str$ - Save program ; ======================== .cmdSAVE JSR PC,EvalStringCR ; Get filename to R4 MOV R4,FILE_NAME MOV SV_PAGE,FILE_START MOV #0,FILE_LOAD+2 MOV SV_TOP,FILE_END MOV #0,FILE_END+2 MOV #&FB00,FILE_LOAD MOV #&FFFF,FILE_LOAD+1 MOV #&0000,FILE_EXEC MOV #&0000,FILE_EXEC+2 ADR FILE_NAME,R1 MOV #0,R0 JMP IO_FILE ; File Functions ; ============== ; =PTR#chn - Read file pointer ; ============================ .fnPTR mov #0,r0 ; R0=0 for read PTR br fnPTR1 ; =EXT#chn - read file extent ; =========================== .fnEXT mov #2,r0 ; R0=2 for read EXT .fnPTR1 mov r0,-(sp) ; Save function number jsr pc,EvalHash ; Step past '#', get integer handle mov (sp)+,r0 ; Get function number back adr ARGS_ADDR,r2 ; Point to ARGS block jsr pc,IO_ARGS ; Call MOS to read PTR mov ARGS_ADDR,r4 mov ARGS_ADDR+2,r3 ; Get returned extent mov #0,r2 ; Return integer rts pc ; =BGET#chn - read byte from channel ; ================================== .fnBGET jsr pc,EvalHash ; Step past '#', get integer handle mov r4,r1 ; R1=handle jsr pc,IO_BGET ; Call MOS to read on this channel mov r0,r4 ; Move to R4 mov #0,r3 ; b16-b31=0 mov #0,r2 ; Return integer rts pc ; =EOF#chn - read end-of-file status ; ================================== .fnEOF jsr pc,EvalHash ; Step past '#', get integer handle mov #127,r0 ; OSBYTE 127,channel to read EOF mov r4,r1 jsr pc,IO_BYTE mov r1,r4 ; Move result to r3/r4 mov r1,r3 mov #0,r2 ; Return integer rts pc ; OSCLI - Execute command ; ======================= .cmdOSCLI .fnOSCLI jsr pc,EvalStringCR mov r4,r0 jsr pc,IO_CLI mov r0,r4 mov #0,r3 mov #0,r2 rts pc ; =OPENIN f$ - open file for input ; ================================ .fnOPENIN mov #&40,r0 ; OPENIN is OSFIND &40 br fnOPEN ; =OPENOUT f$ - open file for output ; ================================== .fnOPENOUT mov #&80,r0 ; OPENOUT is OSFIND &80 br fnOPEN ; =OPENUP f$ - open file for update ; ================================= .fnOPENUP mov #&C0,r0 ; OPENUP is OSFINE &C0 .fnOPEN mov r0,-(sp) jsr pc,EvalStringCR ; Get cr-string mov r4,r1 ; r1=>filename mov (sp)+,r0 ; r0=function jsr pc,IO_FIND mov r0,r4 mov #0,r3 mov #0,r2 rts pc ; Other Commands ; ============== ; TIME=val, TIME$=s$ - set TIME or TIME$ ; ====================================== .cmdTIME cmp r0,#ASC"$" ; Check for '$' beq cmdTIMEs ; TIME$ jsr pc,EvalEqual ; Step past '=', get integer mov r4,MOS_BUF+0 mov r3,MOS_BUF+2 mov #0,MOS_BUF+4 adr MOS_BUF,r1 mov #2,r0 jmp IO_WORD ; Set TIME .cmdTIMEs inc r5 ; Step past '$' jsr pc,CheckEqual ; Check for '=' jsr pc,EvalString ; Get string add r3,r4 ; r4=>end of string adr SV_STRING+1,r1 add r3,r1 ; r1=>past end of string buffer mov r3,r0 ; Save string length beq cmdTIME2 ; Null string .cmdTIMElp movb -(r4),-(r1) ; Copy byte to string buffer dec r3 bne cmdTIMElp .cmdTIME2 ; r1=>SV_STRING+1, r0=string length movb r0,-(r1) ; Put length at start of buffer mov #15,r0 ; TIME$= is OSWORD 15 jmp IO_WORD ; Set TIME$ ; SOUND [ON|OFF|c,a,p,d] - Issue SOUND command ; ============================================ .cmdSOUND ; ENVELOPE a,b,c,d,e,f,g,h,i,j,k,l,m,n ; ==================================== .cmdENVELOPE JSR PC,PrintInline EQUS "Unimplemented system command",13,0 ALIGN RTS PC ; Other Functions ; =============== ; =ADVAL device - read device status ; ================================== .fnADVAL jsr pc,EvalInteger mov r4,r1 mov #&80,r0 jsr pc,IO_BYTE mov r1,r4 mov #0,r3 mov #0,r2 rts pc ; =TIME, =TIME$ - read TIME or TIME$ ; ================================== .fnTIME cmp r0,#ASC"$" beq fnTIMEs ; =TIME$ adr MOS_BUF,r1 mov #1,r0 jsr pc,IO_WORD ; Read TIME mov MOS_BUF+0,r4 mov MOS_BUF+2,r3 mov #0,r2 rts pc .fnTIMEs inc r5 ; Step past '$' adr SV_STRING,r1 ; Point to control block mov #0,(r1) ; Read time as string mov #14,r0 jsr pc,IO_WORD ; Read TIME$ adr SV_STRING,r4 ; Start=MOS_BUF mov #24,r3 ; Length=24 mov #&8000,r2 ; Type=String rts pc