Here's a demo user OSWORD handler. It's very basic, but shows the general outline.
Code:
10 REM > OswDemo/src 20 REM Demonstrate adding an OSWORD via USERV 30 : 40 myOSW=&E0 :REM My OSWORD call number 50 USERV=&200 :REM Vector to user OSWORD routines 60 ctrl=&F0 :REM Points to the control block 70 load%=&FFFF2500 :REM We'll load to &2500 in the I/O processor 80 fname$="OswDEMO" :REM This is what we'll call it 90 DIM mcode% &100 :REM Some space to assemble the code 100 : 110 REM OSWORD control block standard layout 120 REM XY?0 = number of parameter bytes 130 REM XY?1 = number of result bytes 140 REM XY?2 = conventionally command 150 REM XY?3 = conventionally subcommand 160 REM XY!4 onwards any other data 170 : 180 REM Call with code similar to: 190 REM DIM ctrl% 31:X%=ctrl%:Y%=X%DIV256 200 REM X%?0=4 :REM Size of outward control block 210 REM X%?1=32 :REM Size of returned control block 220 REM X%?2=6 :REM Let's do command 6 230 REM !X%=&62004 :REM Alternative way of doing the above 240 REM A%=&E0:CALL &FFF1 :REM Make the OSWORD call 250 REM PRINT $(X%+4) :REM Display the returned data 260 : 270 FOR P=0 TO 1 280 P%=load%:O%=mcode% 290 [OPT P*3+4 300 .L2500 310 JMP L2505 :\ Conventionally, the first two instructions 320 .OldUSERV :\ are the entry point and the old USERV. 330 EQUW L2500 :\ Swapped with USERV to claim. 340 .L2505 350 CMP #myOSW:BEQ L250C :\ If my OSWORD, jump to respond. 360 JMP (OldUSERV) :\ Continue via OldUSERV. 370 : 380 \ Our OSWORD routine. The OSWORD handler has already set up the OSWORD 390 \ call, (&F0) points to the control block, IRQs are disabled, A/X/Y do 400 \ not need to be preserved, IRQs are restored on exit. 410 .L250C 420 LDY #2:LDA (ctrl),Y :\ Get the command in byte 2 430 \ 440 \ For this demo, we'll just use the command byte as an index into some 450 \ data to return. NOTE, this demo does not check for out-of-range values. 460 \ 470 TAX :\ Index into returned data. 480 LDY #4 :\ Return the data at XY+4 onwards. 490 .LOOP 500 LDA data,X :\ Get some data. 510 STA (ctrl),Y :\ Return the data in the control block. 520 INX:INY :\ Step to next byte. 530 CMP #13:BNE LOOP :\ Copy up to a <cr>. 540 RTS :\ All done. Return to OSWORD handler to restore 550 : :\ things and return to the caller. 560 .data 570 EQUS "HELLO WORLD":EQUB 13 :\ Our data 580 \ 590 \ 600 \ To set up the code we need to install it in the I/O processor. The simplest 610 \ way to do this is *RUN it. NOTE, this code does not check if the code already 620 \ exists. 630 .exec% 640 LDY #1 :\ Prepare to swap pairs of bytes. 650 .SetupLp 660 LDX OldUSERV,Y :\ Get new vector stored in old vector 670 LDA USERV,Y :\ Get current system vector 680 STA OldUSERV,Y :\ Keep the current vector in the old vector 690 TXA:STA USERV,Y :\ And set the system vector 700 DEY:BPL SetupLp :\ Do this for both bytes 710 RTS :\ Exit 720 : 730 ]NEXT 740 A$=fname$+" "+STR$~mcode%+" "+STR$~O%+" "+STR$~(exec%OR&FFFF0000)+" "+STR$~load% 750 PRINT"Saving ";A$;:OSCLI "SAVE "+A$:PRINT:END
Statistics: Posted by jgharston — Thu May 29, 2025 1:21 am