General Framework and Explanation

Machine language routines in BASIC all follow the same general steps. You can either POKE it into RAM or pack it into a STRING. For the latter, you would set up a string of the length of the number of bytes in your machine language routine, find the LSB and MSB of that string, load the USR routine start address with that LSB and MSB, and then call the routine. In general the routine would look like:

10 X$="/////////////////////"
20 REM THE NUMBER OF SLASHES SHOULD CORRESPOND TO THE NUMBER OF BYTES
30 A = PEEK(VARPTR(X$)+1) : B = PEEK(VARPTR(X$)+2) : C = A + 256 * B
40 REM THE NEXT STEP DEPENDS ON WHETHER YOU ARE IN LEVEL II BASIC OR IN DISK BASIC, SO THEY WILL SHARE A LINE NUMBER
EITHER
50 POKE 16526, A: POKE 16527, B : 'LEVEL II BASIC METHOD TO DESIGNATE A USR(0) ENTRY POINT
OR
50 DEFUSR0 = C : 'DOS METHOD TO DESIGNATE A USR(0) ENTRY POINT
60 READ D : IF D < 0 THEN END
70 POKE C, D : C = C + 1 : GOTO 60
100 DATA .....

Once run, the routine is called by a simple X=USR(0) command.

Choosing the former will allow you to save a program with the string embedded, and then you would just need lines 10, 30 and 50 in the future.

Of course, there are many other ways to do this, but the concept remains the same. If you don't want to muck around with changing your string length, you can go:

10 CLEAR 100
20 READ D : IF D => 0 THEN X$=X$+CHR$(D) : GOTO 20
30 A = PEEK(VARPTR(X$)+1) : B = PEEK(VARPTR(X$)+2) : C = A + 256 * B
40 REM THE NEXT STEP DEPENDS ON WHETHER YOU ARE IN LEVEL II BASIC OR IN DISK BASIC, SO THEY WILL SHARE A LINE NUMBER
EITHER
50 POKE 16526, A: POKE 16527, B : 'LEVEL II BASIC METHOD TO DESIGNATE A USR(0) ENTRY POINT
OR
50 DEFUSR0 = C : 'DOS METHOD TO DESIGNATE A USR(0) ENTRY POINT
100 DATA .....

Choosing the former will allow you to save a program with the string embedded, and then you would just need lines 10, 30 and 50 in the future.

Rising Saucer Sound

10 X$="////////////////////////////": 'USE 28 SLASHES
100 DATA 205, 127, 10, 77, 68, 62, 1, 105, 211, 255
110 DATA 45, 32, 253, 60, 105, 211, 255, 45
120 DATA 32, 253, 13, 16, 238, 175, 211, 244, 201, -1

Fill the Screen with Character XXXX

10 X$="//////////////////////": 'USE 22 SLASHES
100 DATA 229, 1, 16, 64, 33, 1, 60, 45, 62, XXXX: 'REPLACE XXX WITH THE ASCII VALUE
110 DATA 119, 35, 16, 252, 6, 64, 13, 32, 247
120 DATA 225, 201, -1

Reverse All Graphic Characters

10 X$="///////////////////////": 'USE 23 SLASHES
100 DATA 217, 33, 255, 63, 6, 60, 126, 254, 128
110 DATA 56, 4, 47, 246, 128, 119, 43, 124
120 DATA 184, 48, 242, 217, 201, -1

Move One Block To The Right

10 X$="//////////////////////////////////////////////////": 'USE 50 SLASHES
100 DATA 33, 254, 63, 17, 255, 63, 1, 255, 3 110 DATA 237, 184, 14, 16, 17, 0, 60, 33, 63 120 DATA 0, 25, 237, 160, 229, 209, 121, 183, 32 130 DATA 244, 62, 16, 33, 0, 60, 229, 209, 19 140 DATA 1, 4, 0, 237, 176, 17, 60, 0, 25 150 DATA 61, 183, 32, 240, 201, -1

Save and Restore the Screen

To Save the Screen use GOSUB 11000

To Restore the Screen use GOSUB 12000

10000 REMEMBER TO SET THE MEMORY SIZE TO 31699
10010 FOR ZZ = 31700 TO 31723 : READ D : POKE ZZ, D: NEXT ZZ : END
10020 DATA 33, 0, 60, 17, 254, 123, 1, 0, 4, 237, 176, 201
10030 DATA 33, 254, 123, 17, 0, 60, 1, 0, 4, 237, 176, 201
11000 POKE 16526, 212 : POKE 16527, 123 : Q = USR(0) : RETURN
12000 POKE 16526, 224:  POKE 16527, 123 : Q = USR(0) : RETURN

Rising Saucer Sound Routine

1 M$ = "                              " :' 30 SPACES
2 I = VARPTR(M$) : J = PEEK (I+1) + 256*PEEK(I+2)
3 FOR K = J TO J+26 : READ X : POKE K,X : NEXT K
4 POKE 16526, PEEK(I+1) : POKE 16527, PEEK(I+2)
5 DATA 205, 127, 10, 77, 68, 62, 1, 105, 211, 255, 45, 32, 253
6 DATA 60, 105, 211, 255, 45, 32, 253, 13, 16, 238, 175, 211, 255, 201
7 A=USR(0)
8 FOR T= 1027 TO 755 STEP -1 : G = USR(T) : NEXT T

White Out Routines

To trigger white out use X=USR(0)

1 FOR I = 1 TO 14 : READ P : WR$ = WR$ + CHR$(P) : NEXT
2 POKE 16526, PEEK(VARPTR(WR$)+1)
3 POKE 16527, PEEK(VARPTR(WR$)+2)
4 DATA 33, 0, 60, 54, 255, 17, 1, 60, 1, 255, 3, 237, 176, 201

1 FOR I = 1 TO 13 : READ P : WR$ = WR$ + CHR$(P) : NEXT
2 POKE 16526, PEEK(VARPTR(WR$)+1)
3 POKE 16527, PEEK(VARPTR(WR$)+2)
4 DATA 33, 0, 60, 62, 191, 119, 35, 124, 254, 64, 32, 247, 201

1 DIM A(30) : FOR X = 1 TO 27 : READ A(X) : NEXT X
2 FOR X = 32512 TO 32538 : POKE X,A(X-32511): NEXT X
3 POKE 16526, 0: POKE 16527, 127
4 DATA 33, 0, 60, 17, 1, 60, 1, 255, 3, 54, 191, 237, 176, 6, 5
5 DATA 33, 255, 255, 43, 124, 181, 194, 18, 127, 16, 245, 201

Multiple USR() Calls

The following heading in the machine program permits as many USR calls as memory allows. A call for USR(0) goes to program 0, a call for USR(1) goes to program 1, etc. As it stands it can be used for graphics. If data needs to be passed to the machine program then Memory Size shoul dbe set to the appropriate number of bytes below the origin of the heading, the data poked into this "scratchpad" before calling USR(n), and program (n) then loads from teh "scratchpad" as desired.

The first line of each program should bear the appropriate label - PRGO, PRG1, etc. It is, of course, imperative that no changes be made between CALL 2687 and JP PRGn.

Assembly language heading for multiple USR calls.

                ORG     nnnn
(LABELS)        EQU     (as desired)
                 "              "
                CALL    2687
                XOR     A
                LD      B,3
        DISPL   ADD     A,L
                DEC     B
                JP      NZ,DISPL
                LD      L,A
                LD      BC, $+5
                ADD     HL, BC
                JP      (HL)
                JP      PRG0
                JP      PRG1
                JP      PRG2



                JP      PRGn

Debounce and Break Disable Routine

This routine will provide keyboard debounce with break disabled. Remember to reserve 32742 as the MEMORY SIZE to protect the route and to CSAVE it, as it will NEW when done:

10 CLS : FOR X = 32743 TO 32767 : READ A : POKE X, A : NEXT X
20 POKE 16526, 231 : POKE 16527, 127 : C=USR(0)
30 PRINT @ 512, "OK";
40 FOR D = 1 TO 1000 : NEXT D
50 NEW
60 DATA 33, 238, 127, 34, 22, 64, 201, 205, 227
70 DATA 3, 103, 1, 50, 0, 205, 96, 0, 124, 254
80 DATA 1, 192, 62, 0, 201, 0, 0

NOTE:16526 is 408E in Hex. 408EH is the 2-byte address of USR routine, so poking 231 and 127 is the LSB/MSB of 32743, the entry point of the routine.

Leave a Comment.