|
|
|
PEEK 14316
|
|
The disk status register =255 when there is no expansion interface conncected or powered on.
|
|
PEEK 16549
|
|
If <66 then this is not Disk BASIC
|
|
PEEK 125
|
|
If = 2, its a MODEL II
If = 4, its a MODEL 4/4D
If = 5, its a MODEL 4P
If = 12, its a MODEL 12
|
|
PEEK &H85
|
|
If = &H61 THEN System is TRSDOS 6.1.x
If = &H62 THEN System is TRSDOS 6.2.x
If = &H63 THEN System is LS-DOS 6.3.x
|
|
(PEEK(124)AND &H40)<>0
|
|
Extended Error Message IS displayed.
|
|
(PEEK(119)AND 128)<>0
|
|
Full File Access is ENABLED
|
|
PEEK(&HB94)<>0
|
|
Special Character Mode is ON
|
|
|
|
|
Disable The Keyboard (Programs Still Run)
|
|
POKE 16405, 0
|
|
Enable The Keyboard
|
|
POKE 16405, 1
|
|
Disable the Break Key (L2)
|
|
POKE 16396, 23
|
|
Disable the Break Key (DOS)
|
|
POKE 17170, 175 POKE 17171,201
|
|
Disable the Break Key (NewDOS v2.1)
|
|
POKE 23461,0
|
|
Disable the Break Key (TRSDOS v2.3)
|
|
POKE 23886,0
|
|
Enable the Break Key (L2)
|
|
POKE 16396, 201
|
|
Break Key is ENABLED IF
|
|
(PEEK(124)AND &H10)<>0
|
|
Change BREAK to SHIFT-BREAK
|
|
POKE 16396, 165
|
|
Change BREAK to RESET
|
|
POKE 16396, 233
|
|
Causes BASIC to reinitialize when the BREAK key is hit (L2)
|
|
16396,199
|
|
Determine if ANY key is pressed
|
|
IF PEEK (14463) = 0
|
|
Determine if ANY key other than SHIFT is pressed
|
|
IF PEEK (14591) = 0
|
|
Change the JUMP location on pressing the RESET button
|
|
POKE 16391, LSB
POKE 16392, MSB
|
|
Turn Special Character Set to ON
|
|
ON: POKE &HB94,(PEEK(&HB94) OR 8 )
OFF: POKE &HB94,(PEEK(&HB94) AND 247)
|
|
FULL File Access:
|
|
ENABLED: POKE 119,(PEEK(119) OR &H80)
DISABLED: POKE 119,(PEEK(119) AND &H7F)
|
|
Extended Error Messages:
|
|
ON: POKE 124,(PEEK(124) OR &H40)
OFF: POKE 124,(PEEK(124) AND &HBF)
|
|
Three Line Scroll Protect
|
|
ON: POKE &HB94,(PEEK(0) OR 8)
OFF: POKE &HB94,(PEEK(0) AND 8)
|
|
Change Cursor Character to XX
|
|
POKE &HB98,nn
|
|
|
|
|
| To speed up the Model 4, issue the following commands from basic: |
| X=PEEK(16912) |
| X=X OR 64 |
| POKE(16912,X) |
| OUT 235,X |
|
|
|
|
|
To set SCREEN PRINTER to automatically print
|
|
OUT 254, 255
|
|
Determine the current line position for a Line Printer
|
|
PEEK (16425)
|
|
Determine the position of the print head on the current printer line
|
|
PEEK (16539)
|
|
Determine the lines per page on a line printer
|
|
PEEK (16424) >= Lines per Page + 1 (so normal return is 67)
|
|
Determine the status of a line printer
|
|
PEEK (14312) = 63 (Ready)
PEEK (14312) = 255 (Printer is off)
PEEK (14312) = 191 (Printer Buffer is Full)
PEEK (14312) = 223 or =233 (Out of Paper or offline)
PEEK (14312) > 127 (NOT ready)
|
|
|
|
|
|
Disable List Command
|
|
POKE 16863, 145
POKE 16864, 25
POKE 16865, 26
|
|
Enable List Command
|
|
POKE 16863, 201
|
|
Disable LLIST Command
|
|
POKE 16422, 103
POKE 16423, 00
|
|
Recover a BASIC program which has been destroyed by typing "NEW"?
|
|
POKE 17130,1
SYSTEM
* / 11395
LIST
|
|
Change the JUMP location on pressing / to answer a SYSTEM question
|
|
POKE 16607, LSB
POKE 16608, MSB
|
|
Level I Keyword Shortcuts
|
|
|
PRINT = P.
NEW = N.
RUN = R.
LIST = L.
END = F.
THEN = T.
GOTO = G.
INPUT = IN.
MEM = M.
FOR = F.
|
|
NEXT = N.
STEP (after FOR) = S.
STOP = ST.
CONT = C.
TAB (after PRINT) = T.
INT = I.
GOSUB = GOS.
RETURN = RET.
READ = REA.
DATA = D.
|
|
RESTORE = REST.
ABS = A.
RND = R.
SET = S.
RESET = R.
POINT = P.
PRINT AT = P.A.
CLOAD = CL.
CSAVE = CS.
|
|
|
|
|
|
|
To turn on Cassette Recorder
|
|
OUT 255, 4
|
Stop a Disk Drive from starting and stopping while reading or writing data.
|
|
POKE &H37E1,0
|
If you want everything which is supposed to go to the lineprinter to be sent to the video
|
|
POKE 16422, 88 : POKE 16423, 4
|
|
To restore the lineprinter use:
|
|
POKE 16422, 141 : POKE 16423, 5
|
If you want everything which is supposed to go to the video sent to the lineprinter, use:
|
|
POKE 16414, 141 : POKE 16415, 5
|
|
To restore the video use:
|
|
POKE 16414, 88 : POKE 16415, 4
|
|
Latches Cassette 1
|
|
POKE 14308,0
|
|
Latches Cassette 2
|
|
POKE 14308,1
|
|
|
|
|
|
To convert betweek (X,Y) and PRINT@
|
|
The PRINT@ is INT(Y/3) * 64 + INT(X/2)
The X and Y are Y=3*INT(P/64) : X=2*(P-64*Y/3)
|
|
To change the NUMBER OF FILES under TRSDOS once your in DOS BASIC
|
|
SYSTEM
/ 20992
|
|
|
|
|
Jay Reso of Metairie, La. suggests the following routine for printing the contents of the video display to a lineprinter:
1000 DIM S$(15)
1010 FOR T=0 TO 15
1020 S$(T) = ""
1030 POKE VARPTR(S$(T)),64
1040 POKE VARPTR(S$(T))+1, (T*64 + 15360) AND 255
1050 POKE VARPTR(S$(T))+2, (T*64 + 15360) / 256
1060 NEXT T
1100 FOR T=0 TO 15 : LPRINT S$(T) : NEXT
Line 1020 establishes S$(T) with a location in memory. Line 1030 sets the length of the string to 64 bytes. Lines 1040 and 1050 set the string pointer to the location of the first byte of a video line.
Once you have executed lines 1000-1060, you can execute 1100 at any time and you will get a printed copy of the screen. Remember that you cannot print graphic characters to a lineprinter. One other caution is that you may not ASSIGN values to the strings S$(T). If you try to as-sign values to these strings, you will reset the pointers and you will have to rerun lines 1000-1060.
|
|
Print the Concents of the Screen on a Line Printer
10 CLS
20 CLEAR 500 : DIM S$(15)
30 FOR T = 0 TO 15 : S$(T)=""
40 POKE VARPTR(S$(T)),64
50 POKE VARPTR(S$(T))+1,(T*64+15360) AND 255
60 POKE VARPTR(S$(T))+2,(T*64+15360) / 256
70 NEXT T
80 FOR T = 0 TO 15 : LPRINT S$(T) : NEXT
90 INPUT A$
100 GOTO 80
|
|
M. Thorpe's Screen Graphics Hard Copy Generator
3000 ' SCREEN GRAPHICS HARD COPY GENERATOR
3010 '
3020 FOR X =15360 TO 16383 STEP 64
3030 A=1: B=2: C=1
3040 FOR K=X TO X+63
3050 IF ((PEEK(K)-128) AND A) = A THEN LPRINT"#";:GOTO 3070
3060 LPRINT" ";
3070 IF PEEK(K) =32 GOTO 3090
3080 IF ((PEEK(K)-128) AND B) = B THEN LPRINT"#";:GOTO 3100
3090 LPRINT " ";
3100 NEXT K
3110 LPRINT " "
3120 ON C GOTO 3130,3140,3150
3130 A=4: B=8: C=2: GOTO 3040
3140 A=16 : B=32: C=3: GOTO 3040
3150 NEXT X
3160 RETURN
If you need a sample program to test this with, try the following:
10 DEFINT I,J
20 CLS
30 FOR I = 0 TO 33
40 FOR J = 0 TO 50
50 A=INT(RND(0)+.5)
60 IF A=1 THEN SET(J,I)
70 NEXT J,I
80 GOSUB 3000
90 END
|
|
|
|
|
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
|
|
|
|
|
by Phillip Case
Recently the latest rage in programming has been the use of sound effects in games. In this issue of SoftSide is a program titled SONIC TORPEDOS which has a unique method of permitting you to control the program by voice Input. This article will show you how to use this technique in your programs.
Believe it or not, this technique was accidentally discovered by myself and Chris Freund (familiar name among SoftSide readers) while working on another program.
First, a microphone is required for voice input. It is to be plugged into the MIC jack of your cassette recorder. Then unplug both the AUX and REM plugs and leave them loose. When this is done, depress the tab sensor in the cassette bay, the RECORD and the PLAY keys all together.
The program commands themselves are relatively simple.
The microphone causes the value of the cassette to change whenever sound is sensed. To check the value of the cassette port use the INP(255) command. This will give you a value to work with in your program. The value of the port will be 255, if sound has been detected, and 127 if not. Use the INP(255) function as you would the INKEY$, i.e., within a loop.
Once sound has been detected, the value of the cassette port will remain at 255 until you either clear the screen (CLS) or home the cursor (PRINTCHR$(28)). This must be done to reset the cassette port for receiving sound. It is suggested that this be done just prior to checking the port so that no background sound be picked up.
There is a little problem that arises if you are in the character mode and you are trying to use this technique. Because the 32 character mode is controlled via the same port as the cassette recorder, the values of the port are different when you are in that mode. For the same reason it is possible to get double size letters on Level I with a little work.
Below is a table showing the various values under different conditions.
| Mode | 64 Char | 32 Char |
| No Sound | 127 | 63 |
| Sound | 255 | 191 |
Here are two examples of how to use the sound input in your programs.
The following program will print 'SOUND!!!' in the upper-left hand corner of your screen whenever the computer is picking up input from the microphone.
10 CLS: PRINT CHR$(28) : IF INP(255) = 255 THEN PRINT "SOUND!!!" : GOTO 10 ELSE 10
The following program will display a graphic representation of your voice:
10 CLS : FOR X = 0 to 127 : PRINT CHR$(28): IF INP (255)=255 THEN Y=22 ELSE Y=23
20 SET (X,Y): NEXT : RUN
|
|
|
|
Super Sorting - by T R Dettman
|
|
| The next time you sort a list of items in your computer, try this experiment. Put an AM radio next to the computer, tuned away from any station. With this, you can actually hear the computer 'think'. |
| If you try this, you will find that during the sort, a large amount of time will be spent doing something which changes the pattern of the sound completely. This change is the bane of most sorting techniques on the TRS-80, and it is called "Memory Management". |
| Memory Management |
| To understand memory management, we have to look at how the computer stores information. For numbers this is simple since each variable is assigned space in memory for its value, resetting it doesn't change where it is. |
| However, strings are handled differently. When we read in strings, the computer stores them starting at the top of free string memory (remember CLEAR N, it sets aside N bites for strings. RUN automatically does a CLEAR 50). The beginning of each string is recorded along with the length of the string in a location in memory provided for this. The VARPTR function gives you that location |
| If you have a string in memory called A$, its location is given by: |
PEEK(VARPTR(A$)+1) + PEEK(VARPTR(A$)+2)*256
|
| (see the Level II Reference Manual. p8/9). |
| The length of the string is: |
PEEK (VARPTR(A$))
|
| As you add strings into string space, they are added one after another as shown in the diagram. |
| When you reset the value of a string, the pointers to the string in memory are reset to their new values by the interpreter. But this is not all, since the string is treated as a new string and the old location of the string is not recovered. |
| A typical statement in a sorting program which changes one string for another is: |
| TS=A$(I):A$(l)=A$(J):A$(J)=TS |
| Even though the strings are already occupying space in memory, this statement generates THREE NEW STRINGS and adds them into the string space at the bottom. |
| When you fill up the string space (which will happen very quickly), the computer pauses to reorganize the memory and compact the string space by getting rid of unused space. During this time, your program just waits. |
| Even with the best sorting algorithm, as much as 90% of the computing time for the sort will be in memory management. In order to get efficient sorts we have to get rid of this wasted time. |
| Sorting with VARPTR |
| A significant improvement in sorting time (from 4 hrs to 8 ½ minutes, for 450 items), is gained by redoing the program statement above that swaps strings as follows: |
I1= PEEK (VARPTR(A$(I))):
I2= PEEK (VARPTR(A$(I))+1):
I3= PEEK (VARPTR(A$(I))+2)
J1=PEEK (VARPTR(A$(J))):
J2=PEEK (VARPTR(A$(J))+1):
J3=PEEK (VARPTR(A$(J))+2)
POKE (VARPTR(A$(I))),J1:
POKE (VARPTR(A$(I))+1),J2:
POKE (VARPTR(A$(I))+2),J3
POKE (VARPTR(A$(J))),I1:
POKE (VARPTR(A$(J))+1 ),I2:
POKE (VARPTR(A$(J))+2),I3
|
| This set of statements creates no new strings in memory. It only changes the pointers to the strings. On large sorts, the improvement by using this technique is phenomenal. On a sort of 450 items in a mailing list, we had an improvement from 4 hours without this technique, to 8½ minutes with it. This sort has now been included in our own mailing list program as well as Peripheral People's Mailroom. |
| As this is being typed up for publication, we have seen an article elsewhere giving essentially the same sorting technique. We discovered only one minor problem with the way that it accomplishes the switch. |
| It uses the following statements to switch the pointers: |
T1=VARPTR(A$(I))
T2=VARPTR(A$(J))
FOR Z=0 TO 2
A1=PEEK(T1 + Z)
A2=PEEK(T2 + Z)
POKE (T1+Z),A2
POKE (T2+Z),A1
NEXT Z
|
| I found that the technique works well on long sorts, but that the pointers were dynamically allocated (a 25 cent buzzword for saying that they can move) on short sorts, say less than 10 items. |
| For short sorts, setting the values T1 and T2 resulted in not getting the pointer correctly. This has disastrous results since the pointers become random and you soon find that your strings begin to take on a funny look. |
| On one sort, some of the pointers actually wound up saying that the strings they referred to were in Level II ROM! In order to prevent this, the statements can be changed to be equivalent with mine. |
FOR Z = 0 TO 2
Al = PEEK(VARPTR(A$(I))+Z)
A2 = PEEK(VARPTR(A$(J))+Z)
POKE (VARPTR(A$(I)) + Z), A2
POKE (VARPTR(A$(J)) + Z), A1
NEXT Z
|
| Further Improvements |
| Still another improvement comes from changing all of the variables in the program to integers, except those that must be real or string variables. |
|
|
|