Appendix C
Machine Language
Editor for Atari and
Commodore


Charles Brannon

Have you ever typed in a long machine language program? Chances are you typed in hundreds of DATA statements, numbers, and commas. You're never sure if you've typed them in right. So you go back, proofread, try to run the program, crash, go back and proofread again, correct a few typing errors, run again, crash, recheck your typing-frustrating, isn't it?
    Until now, though, that has been the best way to enter machine language into your computer. Unless you happen to own an assembler and are willing to wrangle with machine language on the assembly level, it is much easier to enter a BASIC program that reads the DATA statements and POKEs the numbers into memory.
    Some of these BASIC loaders, as they are known, use a checksum to see if you've typed the numbers correctly. The simplest checksum is just the sum of all the numbers in the DATA statements. If you make an error, your checksum will not match up. Some programmers make the task easier by calculating checksums every ten lines or so, and you can thereby locate your errors more easily.

Almost Foolproof
"MLX" lets you type in long machine language (ML) listings with almost foolproof results. Using MLX, you enter the numbers from a special list that looks similar to BASIC DATA statements. MLX checks your typing on a line-by-line basis. It won't let you enter illegal characters when you should be typing numbers, such as a lowercase L for a 1 or an O for a 0. It won't let you enter numbers greater than 255, which are not permitted in ML DATA statements. It will prevent you from entering the wrong numbers on the wrong line. In short, MLX should make proofreading obsolete!
    In addition, MLX will generate a ready-to-use tape or disk file. For the Commodore, you can then use the LOAD command to read the program into the computer, just as you would with any program. Specifically, you enter:

LOAD "filename",1,1 (for tape)

or
LOAD "filename",8,1 (for disk)

    To start LADS you need to type SYS 11000 (Commodore). For complete instructions for the use of LADS, please read Appendix A.
For the Atari, MLX will create a binary file for use with DOS. Atari MLX can create a boot disk or tape version of LADS, but this is not recommended.

Getting Started
To get started, type in and save MLX (VIC owners must have at least 8K of extra memory attached). When you are ready to enter LADS using MLX, Commodore 64 and VIC owners should enter the line below before loading MLX:

POKE 55,0: POKE 56,42: CLR

Commodore PET/CBM owners should use:

POKE 52,0: POKE 53,42: CLR

When you're ready to type in LADS, the program will ask you for several numbers: the starting address and the ending address. In addition, the Atari MLX will request a "Run/Init Address".
    Below are the numbers you'll need.

PET/CBM, VIC and Commodore 64:
    Starting address 11000
    Ending address 15985

Atari:
Starting address 32768
Ending address 39607
Run/Init address 32768

    The Atari version will then ask you to press either T for a boot tape, or D for disk; press D. Next, you'll be asked if you want to generate a boot disk or a binary file; press F.
    Next you'll see a prompt. The prompt is the current line you are entering from the listing. Each line is six numbers plus a checksum. If you enter any of the six numbers wrong, or enter the checksum wrong, MLX will ring a buzzer and prompt you to reenter the line. If you enter it correctly, a pleasant bell tone will sound and you proceed to the next line.

A Special Editor
You are not using the normal screen editor with MLX. For example, it will accept only numbers as input. If you need to make a correction, press the DEL/BACKS key (Atari) or the INST/DEL key (Commodore). The entire number is deleted. You can press it as many times as necessary back to the start of the line. If you enter three-digit numbers as listed, the computer will automatically print the comma and prepare to accept the next number. If you enter less than three digits (by omitting leading zeros), you can press either the comma, space bar, or RETURN key to advance to the next number. When you get to the checksum value, the Atari MLX will emit a low drone to remind you to be careful. The checksum will automatically appear in inverse video; don't worry, it's highlighted for emphasis.
     When testing MLX, we've found that it makes entering long listings extremely easy. We have tested MLX with people lacking any computer background whatsoever. No one here has managed to enter a listing wrong with it.

Done at Last!
When you finish typing (assuming you type the entire listing in one session), you can then save the completed program on tape or disk. Follow the screen instructions. (For Atari we suggest that you use the filename AUTORUMSYS when saving a copy of LADS. This way LADS will automatically load and run when you boot up your computer.) If you get any errors while saving, you probably have a bad disk, or the disk is full, or you made a typo when entering the actual MLX program. (Remember, it can't check itself!)

Command Control
What if you don't want to enter the whole program in one sitting? MLX lets you enter as much as you want, save that portion, and then reload the file from tape or disk when you want to continue. MLX recognizes these few commands:
      S: Save
      L: Load
      N: New Address
      D: Display
    For the Atari, hold down the CTRL key while you type the appropriate key. Hold down SHIFT on Commodore machines to enter a command key. You will jump out of the line you've been typing, so it's best to perform these commands at a new prompt. Use the Save command to save what you've been working on. It will write the tape or disk file as if you've finished, but the tape or disk won't work, of course, until you finish the typing. Remember what address you stop on. The next time you run MLX, answer all the prompts as you did before, then insert the disk or tape. When you get to the entry prompt, press CTRL-L (Atari) or SHIFT-L (Commodore) to reload the file into memory. You'll then use the New Address command to resume typing.

New Address and Display
Here's how the New Address command works. After you press SHIFT-N or CTRL-N, enter the address where you previously stopped. The prompt will change, and you can then continue typing. Always enter a New Address that matches up with one of the line numbers in the special listing, or else the checksum won't match up.
    You can use the Display command to display a section of your typing. After you press CTRL-D or SHIFT-D, enter two addresses within the line number range of the listing. You can abort the listing by pressing any key.

Tricky Business
The special commands may seem a little confusing at first, but as you work with MLX, they will become easy and valuable. What if you forgot where you stopped typing, for instance? Use the Display command to scan memory from the beginning to the end of the program. You can stop a listing by hitting any key.

Making Copies
You can use the MLX Save and Load commands to make copies of the completed ML program. Use Load to reload the tape or disk, then insert a new tape or disk and use the Save command to make a new copy.

PET and VIC Users
The Commodore 64, PET, and VIC data are almost exactly the same. There are some lines, though, that are different. Commodore 64, PET, and VIC owners should use the Commodore 64 data (Program B-1) with MLX. VIC owners should substitute the lines found in Program B-2 (VIC) for the same lines in Program B-1. PET owners should type in and save the 64 data, then make the necessary changes shown in Program B-3a and B-3b using the built-in PET monitor. Commodore 64 users should use the data in Program B-1 as is.
    We hope you will find MLX to be a true labor-saving utility. Since it has been thoroughly tested by entering actual programs, you can count on it as an aid for generating bug-free machine language. And be sure to save MLX; it will be used for future all machine language programs in COMPUTE!, COMPUTE!'s Gazette, and COMPUTE! Books.

Program C-1. Commodore 64 MLX

Refer to Appendix E "How to Type In BASIC Programs" before entering this program.

100 PRINT"{CLR}6";CHR$(142);CHR$(8);:POKE53281,1
    :POKE53280,1
101 POKE 788,52:REM DISABLE RUN/STOP
110 PRINT"{RVS}{39 SPACES}";
120 PRINT"{RVS}{14 SPACES}{RIGHT}{OFF}*£{RVS}
    {RIGHT} {RIGHT}{2 SPACES}*{OFF}*
£{RVS}£
    {RVS}{14 SPACES)";
130 PRINT"{RVS}{14 SPACES}{RIGHT}G{RIGHT}
    {2 RIGHT) {OFF}£{RVS}£*{OFF}*{RVS}
    {14 SPACES}";
140 PRINT"{RVS}{41 SPACES}"
200 PRINT"{2 DOWN}{PUR}{BLK}{9 SPACES}MACHINE LANG
    UAGE EDITOR{5 DOWN}"
210 PRINT"5{2 UP}STARTING ADDRESS?{8 SPACES)
    {9 LEFT}";
215 INPUTS:F=1-F:C$=CHR$(31+119*F)
220 IFS<2560R(S>40960ANDS<49152)ORS>53247THENGOSUB
    3000:GOTO210
225 PRINT:PRINT:PRINT
230 PRINT"5{2 UP}ENDING ADDRESS?{8 SPACES}
    {9 LEFT}";:INPUTE:F=1-F:C$=CHR$(31+119*F)
240 IFE<2560R(E>40960ANDE<49152)ORE>53247THENGOSUB
    3000:GOTO230
250 IFE<STHENPRINTC$;"{RVS}ENDING < START
    {2 SPACES}":GOSUB1000:GOTO 230
260 PRINT:PRINT:PRINT
300 PRINT"{CLR}";CHR$(14):AD=S:POKEV+21,0
310 A=1:PRINTRIGHT$("0000"+MID$(STR$(AD),2),5);":"
    ;
315 FORJ=ATO6
320 GOSUB570:IFN=-1THENJ=J+N:GOTO320
390 IFN=-211THEN 710
400 IFN=-204THEN 790
410 IFN=-206THENPRINT:INPUT"{DOWN}ENTER NEW ADDRES
    S";ZZ
415 IFN=-206THENIFZZ<SORZZ>ETHENPRINT"{RVS}OUT OF
    {SPACE}RANGE":GOSUB1000:GOTO410
417 IFN=-206THENAD=ZZ:PRINT:GOTO310
420 IF N<>-196 THEN 480
430 PRINT?:INPUT"DISPLAY:FROM";F:PRINT,"TO",:INPUTT
440 IFF<SORF>EORT<SORT>ETHENPRINT"AT LEAST";S;"
    {LEFT}, NOT MORE THAN";E:GOTO430
450 FORI=FTOTSTEP6:PRINT:PRINTRIGHT$("0000"+MID$(S,
    TR$(I),2),5);":";
451 FORK=0T05:N=PEEK(I+K):PRINTRIGHT$("00"+MID$(ST
    R$(N),2),3);",";
460 GETA$:IFA$>""THENPRINT:PRINT:GOTO310
470 NEXTK:PRINTCHR$(20);:NEXTI:PRINT:PRINT:GOTO310
480 IFN<0 THEN PRINT:GOTO310
490 A(J)=N:NEXTJ
500 CKSUM=AD-INT(AD/256)*256:FORI=1TO6:CKSUM=(CKSU
    M+A(I))AND255:NEXT
510 PRINTCHR$(18);:GOSUB570:PRINTCHR$(146);
511 IFN=-1THENA=6:GOTO315
515 PRINTCHR$(20):IFN=CKSUMTHEN530
520 PRINT:PRINT"LINE ENTERED WRONG : RE-ENTER":PRI
    NT:GOSUB1000:GOTO310
530 GOSUB2000
540 FORI=1TO6:POKEAD+I-1,A(I):NEXT:POKE54272,0:POK
    E54273,0
550 AD=AD+6:IF AD<E THEN 310
560 GOTO 710
570 N=0:Z=0
580 PRINT"£";
581 GETA$:IFA$=""THEN581
585 PRINTCHR$(20);:A=ASC(A$):IFA=13ORA=44ORA=32THE
    N670
590 IFA>128THENN=-A:RETURN
600 IFA<>20 THEN 630
610 GOSUB690:IFI=lANDT=44THENN=-1:PRINT"{OFF}
    {LEFT} {LEFT}";:GOTO690
620 GOTO570
630 IFA<48ORA>57THEN580
640 PRINTA$;:N=N*10+A-48
650 IFN>255 THEN A=20:GOSUB1000:GOTO600
660 Z=Z+1:IFZ<3THEN580
670 IFZ=0THENGOSUB1000:GOTO570
680 PRINT",";:RETURN
690 S%=PEEK(209)+256*PEEK(210)+PEEK(211)
691 FORI=1TO3:T=PEEK(S%-I)
695 IFT<>44ANDT<>58THENPOKES%-I,32:NEXT
700 PRINTLEFT$("{3 LEFT}",I-1);:RETURN
710 PRINT"{CLR}{RVS}*** SAVE ***{3 DOWN}"
715 PRINT"{2 DOWN}(PRESS {RVS}RETURN{OFF} ALONE TO
    CANCEL SAVE){DOWN}"
720 F$="":INPUT"{DOWN} FILENAME",F$:IFF$=""THENPRI
    NT:PRINT:GOTO310
730 PRINT:PRINT"{2 DOWN}{RVS}T{OFF}APE OR {RVS}D
    (OFF}ISK: (T/D)"
740 GETA$:IFA$<>"T"ANDA$<>"D"TFiEN740
750 DV=1-7*(A$="D"):IFDV=8THENF$="0:"+F$:OPEN15,8,
    15,"S"+F$:CLOSE15
760 T$=F$:ZK=PEEK(53)+256*PEEK(54)-LEN(T$):POKE782
    ,ZK/256
762 POKE781,ZK-PEEK(782)*256:POKE780,LEN(T$):SYS65
    469
763 POKE780,1:POKE781,DV:POKE782,1:SYS65466
765 K=S:POKE254,K/256:POKE253,K-PEEK(254)*256:POKE
    780,253
766 K=E+1:POKE782,K/256:POKE781,K-PEEK(782)*256:SY
    S65496
770 IF(PEEK(783)AND1)OR(191ANDST)THEN780
775 PRINT"{DOWN}DONE.{DOWN}":GOTO310
780 PRINT"{DOWN}ERROR ON SAVE.(2 SPACES}TRY AGAIN.
    ":IFDV=ITHEN720
781 OPEN15,8,15:INPUT#15,E1$,E2$:PRINTE1$;E2$:CLOS
    E15:GOTO720
790 PRINT"{CLR}{RVS}*** LOAD ***(2 DOWN}"
795 PRINT"{2 DOWN}(PRESS {RVS}RETURN{OFF} ALONE TO
    CANCEL LOAD)"
800 F$="":INPUT"(2 DOWN) FILENAME";F$:IFF$=""THENP
    RINT:GOTO310
810 PRINT:PRINT"{2 DOWN}{RVS}T{OFF}APE OR {RVS}D
    {OFF}ISK: (T/D)"
820 GETA$:IFA$<>"T"ANDA$<>"D"THEN820
830 DV=1-7*(A$="D"):IFDV=8THENF$="0:"+F$
840 T$=F$:ZK=PEEK(53)+256*PEEK(54)-LEN(T$):POKE782
    ,ZK/256
841 POKE781,ZK-PEEK(782)*256:POKE780,LEN(T$):SYS65
    469
845 POKE780,1:POKE781,DV:POKE782,1:SYS65466
850 POKE780,0:SYS65493
860 IF(PEEK(783)AND1)OR(191ANDST)THEN870
865 PRINT"{DOWN}DONE.":GOTO310
870 PRINT"{DOWN}ERROR ON LOAD.(2 SPACES}TRY AGAIN.
    {DOWN}":IFDV=1THEN800
880 OPEN15,8,15:INPUT#15,El$,E2$:PRINTEI$;E2$:CLOS
    E15:GOTO800
1000 REM BUZZER
1001 POKE54296,15:POKE54277,45:POKE54278,165
1002 POKE54276,33:POKE 54273,6:POKE54272,5
1003 FORT=1TO200:NEXT:POKE54276,32:POKE54273,0:POK
     E54272,0:RETURN
2000 REM BELL SOUND
2001 POKE54296,15:POKE54277,0:POKE54278,247
2002 POKE 54276,17:POKE54273,40:POKE54272,0
2003 FORT=1TO100:NEXT:POKE54276,16:RETURN
3000 PRINTC$;"{RVS}NOT ZERO PAGE OR ROM":GOTO1000


Program C-2. VIC MLX

Refer to Appendix E "How to Type In BASIC Programs" before entering this program.

100 PRINT"{CLR}{PUR}",CHR$(142);CHR$(8);
101 POKE 788,194:REM DISABLE RUN/STOP
110 PRINT"{RVS}{14 SPACES}"
120 PRINT"{RVS} {RIGHT}{OFF}*£{RVS}{RIGHT}
    {RIGHT}{2 SPACES}*{OFF}*£{RVS}£{RVS} "
130 PRINT"{RVS} {RIGHT}G{RIGHT} {2 RIGHT} {OFF}
    £{RVS}£*{OFF}*{RVS} "
140 PRINT"{RVS}{14 SPACES}"
200 PRINT"{2 DOWN}{PUR}{BLK}A FAILSAFE MACHINE":PR
    INT"LANGUAGE EDITOR{5 DOWN}"
210 PRINT"{BLK}{3 UP}STARTING ADDRESS":INPUTS:F=1-
    F:C$=CHR$(31+119*F)
220 IFS<256ORS>32767THENGOSUB3000:GOTO210
225 PRINT:PRINT:PRINT:PRINT
230 PRINT"{BLK}{3 UP}ENDING ADDRESS":INPUTE:F=1-F:
    C$=CHR$(31+119*F)
240 IFE<256ORE>32767THENGOSUB3000:GOTO230
250 IFE<STHENPRINTC$;"{RVS}ENDING < START
    {2 SPACES}":GOSUB1000:GOTO 230
260 PRINT:PRINT:PRINT
300 PRINT"{CLR}";CHR$(14):AD=S
310 PRINTRIGHT$("0000"+MID$(STR$(AD),2),5);":";:FO
    RJ=lTO6
320 GOSUB570:IFN=-1THENJ=J+N:GOTO320
390 IFN=-211THEN 710
400 IFN=-204THEN 790
410 IFN=-206THENPRINT:INPUT"{DOWN}ENTER NEW ADDRES
    S";ZZ
415 IFN=-206THENIFZZ<SORZZ>ETHENPRINT"{RVS}OUT OF
    {SPACE}RANGE":GOSUB1000:GOTO410
417 IFN=-206THENAD=ZZ:PRINT:GOTO310
420 IF N<>-196 THEN 480
430 PRINT:INPUT"DISPLAY:FROM";F:PRINT,"TO";:INPUTT
440 IFF<SORF>EORT<SORT>ETHENPRINT"AT LEAST";S;"
    {LEFT}, NOT MORE THAN";E:GOTO430
450 FORI=FTOTSTEP6:PRINT:PRINTRIGHT$("0000"+MID$(S
    TR$(I),2),5);":";
455 FORK=OT05:N=PEEK(I+K):IFK=3THENPRINTSPC(10);
457 PRINTRIGHT$("00"+MID$(STR$(N),2),3);",";
460 GETA$:IFA$>""THENPRINT:PRINT:GOTO310
470 NEXTK:PRINTCHR$(20);:NEXTI:PRINT:PRINT:GOTO310
480 IFN<0 THEN PRINT:GOTO310
490 A(J)=N:NEXTJ
500 CKSUM=AD-INT(AD/256)*256:FORI=1TO6:CKSUM=(CKSU
    M+A(I))AND255:NEXT
510 PRINTCHR$(18);:GOSUB570:PRINTCHR$(20)
515 IFN=CKSUMTHEN530
520 PRINT:PRINT"LINE ENTERED WRONG":PRINT"RE-ENTER
    ":PRINT:GOSUB1000:GOTO310
530 GOSUB2000
540 FORI=1TO6:POKEAD+I-1,A(I):NEXT
550 AD=AD+6:IF AD<E THEN 310
560 GOTO 710
570 N=0:Z=0
580 PRINT"+";
581 GETA$:IFA$=""THEN581
585 PRINTCHR$(20);:A=ASC(A$):IFA=13ORA=44ORA=32THE
    N670
590 IFA>128THENN=-A:RETURN
600 IFA<>20 THEN 630
610 GOSUB690:IFI=lANDT=44THENN=-l:PRINT"{LEFT}
    {LEFT}";:GOTO690
620 GOTO570
630 IFA<48ORA>57THEN580
640 PRINTA$;:N=N*10+A-48
650 IFN>255 THEN A=20:GOSUB1000:GOTO600
660 Z=Z+1:IFZ<3THEN580
670 IFZ=0THENGOSUB1000:GOTO570
680 PRINT",";:RETURN
690 S%=PEEK(209)+256*PEEK(210)+PEEK(211)
692 FORI=1TO3:T=PEEK(S%-I)
695 IFT<>44ANDT<>58THENPOKES%-I,32:NEXT
700 PRINTLEFT$("{3 LEFT}",I-1);:RETURN
710 PRINT"{CLR}{RVS}*** SAVE ***{3 DOWN}"
720 INPUT"{DOWN} FILENAME";F$
730 PRINT:PRINT"{2 DOWN}{RVS}T{OFF}APE OR {RVS}D
    {OFF}ISK: (T/D)"
740 GETA$:IFA$<>"T"ANDA$<>"D"THEN740
750 DV=1-7*(A$="D"):IFDV=8THENF$="0:"+F$
760 T$=F$:ZK=PEEK(53)+256*PEEK(54)-LEN(T$):POKE782
    ,ZK/256
762 POKE781,ZK-PEEK(782)*256:POKE780,LEN(T$):SYS65
    469
763 POKE780,1:POKE781,DV:POKE782,1:SYS65466
765 POKE254,S/256:POKE253,S-PEEK(254)*256:POKE780,
    253
766 POKE782,E/256:POKE781,E-PEEK(782)*256:SYS65496
770 IF(PEEK(783)AND1)OR(ST AND191)THEN780
775 PRINT"{DOWN}DONE.":END
780 PRINT"{DOWN}ERROR ON SAVE.{2 SPACES}TRY AGAIN.
    ":IFDV=ITHEN720
781 OPEN15,8,15:INPUT#15,E1$,E2$:PRINTE1$;E2$:CLOS
    E15:GOTO720
782 GOTO720
790 PRINT"{CLR}{RVS}*** LOAD ***{2 DOWN}"
800 INPUT"{2 DOWN} FILENAME";F$
810 PRINT:PRINT"{2 DOWN}{RVS}T{OFF}APE OR {RVS}D
    {OFF}ISK: (T/D)"
820 GETA$:IFA$<>"T"ANDA$<>"D"THEN820
830 DV=1-7*(A$="D"):IFDV=8THENF$="0:"+F$
840 T$=F$:ZK=PEEK(53)+256*PEEK(54)-LEN(T$):POKE782
    ,ZK/256
841 POKE781,ZK-PEEK(782)*256:POKE780,LEN(T$):SYS65
    469
845 POKE780,1:POKE781,DV:POKE782,1:SYS65466
850 POKE780,0:SYS65493
860 IF(PEEK(783)AND1)OR(ST AND191)THEN870
865 PRINT"{DOWN}DONE.":GOTO310
870 PRINT"{DOWN}ERROR ON LOAD.{2 SPACES}TRY AGAIN.
    {DOWN}":IFDV_E=ITHEN800
880 OPEN15,8,15:INPUT#15,E1$,E2$:PRINTE1$;E2$:CLOS
    E15:GOTO800
1000 REM BUZZER
1001 POKE36878,15:POKE36874,190
1002 FORW=1TO300:NEXTW
1003 POKE36878,0:POKE36874,0:RETURN
2000 REM BELL SOUND
2001 FORW=15T00STEP-1:POKE36878,W:POKE36876,240:NE
     XTW
2002 POKE36876,0:RETURN
3000 PRINTC$;"{RVS}NOT ZERO PAGE OR ROM":GOTO1000


Program C-3. PET MLX

Refer to Appendix E "How to Type In BASIC Programs" before entering this program.

100 PRINT"{CLR}";CHR$(142):POKE53,43:CLR
110 PRINT"{RVS}{38 SPACES}"
120 PRINT"{RVS}{18 SPACES}MLX{17 SPACES}"
140 PRINT"{RVS}{38 SPACES}"
200 PRINT"{2 DOWN} MACHINE LANGUAGE EDITOR PET VER
    SION{5 DOWN}"
210 PRINT"{2 UP}STARTING ADDRESS?{8 SPACES}
    {9 LEFT}";
215 INPUTS
220 IFS<256ORS>32767THENGOSUB3000:GOTO210
225 PRINT:PRINT:PRINT
230 PRINT"{2 UP}ENDING ADDRESS?{8 SPACES}{9 LEFT}"
    ;:INPUTE
240 IFE<256ORE>32767THENGOSUB3000:GOTO230
250 IFE<STHENPRINTC$;"{RVS}ENDING < START
    {2 SPACES}":GOSUB1000:GOTO 230
260 PRINT:PRINT:PRINT
300 PRINT"{CLR}";CHR$(14):AD=S
310 A=1:PRINTRIGHT$("0000"+MID$(STR$(AD),2),5);":"
    ;
315 FORJ=ATO6
320 GOSUB570:IFN=-1THENJ=J+N:GOTO320
390 IFN=-211THEN 710
400 IFN=-204THEN 790
410 IFN=-206THENPRINT:INPUT"{DOWN}ENTER NEW ADDRES
    S" ; ZZ
415 IFN=-206THENIFZZ<SORZZ>ETHENPRINT"{RVS}OUT OF
    {SPACE}RANGE":GOSUB1000:GOTO410
417 IFN=-206THENAD=ZZ:PRINT:GOTO310
420 IF N<>-196 THEN 480
430 PRINT:INPUT"DISPLAY:FROM";F:PRINT,"TO";:INPUTT
440 IFF<SORF>EORT<SORT>ETHENPRINT"AT LEAST";S;"
    {LEFT}, NOT MORE THAN";E:GOTO430
450 FORI=FTOTSTEP6:PRINT:PRINTRIGHT$("0000"+MID$(S
    TR$(I),2),5);":";
451 FORK=0TO5:N=PEEK(I+K):PRINTRIGHT$("00"+MID$(ST
    R$(N),2),3);",";
460 GETA$:IFA$>""THENPRINT:PRINT:GOTO310
470 NEXTK:PRINTCHR$(20);:NEXTI:PRINT:PRINT:GOTO310
480 IFN<0 THEN PRINT:GOTO310
490 A(J)=N:NEXTJ
500 CKSUM=AD-INT(AD/256)*256:FORI=1TO6:CKSUM=(CKSU
    M+A(I))AND255:NEXT
510 PRINTCHR$(18);:GOSUB570:PRINTCHR$(146);
511 IFN=-1THENA=6:GOTO315
515 PRINTCHR$(20):IFN=CKSUMTHEN530
520 PRINT:PRINT"LINE ENTERED WRONG : RE-ENTER":PRI
    NT:GOSUB1000:GOTO310
530 GOSUB2000
540 FORI=1TO6:POKEAD+I-1,A(I):NEXT
550 AD=AD+6:IF AD<E THEN 310
560 GOTO 710
570 N=0:Z=0
580 PRINTCHR$(168);
581 GETA$:IFA$=""THEN581
585 PRINTCHR$(20);:A=ASC(A$):IFA=130RA=440RA=32THE
    N670
590 IFA>128THENN=-A:RETURN
600 IFA<>20 THEN 630
610 GOSUB690:IFI=lANDT=44THENN=-1:PRINT"{OFF}
    {LEFT} {LEFT}";:GOTO690
620 GOTO570
630 IFA<48ORA>57THEN580
640 PRINTA$;:N=N*10+A-48
650 IFN>255 THEN A=20:GOSUB1000:GOTO600
660 Z=Z+l:IFZ<3THEN580
670 IFZ=0THENGOSUB1000:GOTO570
680 PRINT",";:RETURN
690 SS=PEEK(196)+256*PEEK(197)+PEEK(198)
691 FORI=1TO3:T=PEEK(SS-I)
695 IFT<>44ANDT<>58THENPOKESS-I,32:NEXT
700 PRINTLEFT$("{3 LEFT}",I-1);:RETURN
710 PRINT"{CLR}{RVS}*** SAVE ***{3 DOWN}"
715 PRINT"{2 DOWN}(PRESS{RVS}RETURN{OFF} ALONE TO
    CANCEL SAVE){DOWN}"
720 F$="":INPUT"{DOWN} FILENAME? *{3 LEFT}";F$:IFF
    $="*"THENPRINT:PRINT:GOTO310
730 PRINT:PRINT"{2 DOWN}{RVS}T{OFF}APE OR {RVS}D
    {OFF}ISK: (T/D)"
740 GETA$:IFA$<>"T"ANDA$<>"D"THEN740
750 DV=1-7*(A$="D"):IFDV=8THENF$="0:"+F$:OPEN15,8,
    15,"S"+F$:CLOSE15
760 T$=F$:ZK=PEEK(50)+256*PEEK(51)-LEN(T$):POKE219
    ,ZK/256
762 POKE218,ZK-PEEK(219)*256:POKE209,LEN(T$)
763 POKE210,1:POKE211,0:POKE212,DV
765 K=S:POKE252,K/256:POKE251,K-PEEK(252)*256
766 K=E+1:POKE202,K/256:POKE201,K-PEEK(202)*256:SY
    S63203:REM 63140 FOR 3.0
770 IF(191ANDST)THEN780
775 PRINT"{DOWN}DONE.{DOWN}":GOTO310
780 PRINT"{DOWN}ERROR ON SAVE.{2 SPACES}TRY AGAIN.
    ":IFDV=ITHEN720
781 OPEN15,8,15:INPUT#15,El$,E2$:PRINTE1$;E2$:CLOS
    E15:GOTO720
790 PRINT"{CLR}{RVS}*** LOAD ***{2 DOWN}"
795 PRINT"{2 DOWN}(PRESS {RVS}RETURN{OFF} ALONE TO
    CANCEL LOAD)"
800 F$="":INPUT"{2 DOWN} FILENAME? *{3 LEFT}";F$:I
    FF$="*"THENPRINT:PRINT:GOTO310
810 PRINT:PRINT"{2 DOWN}{RVS}T{OFF}APE OR {RVS}D
    {OFF}ISK: (T/D)"
820 GETA$:IFA$<>"T"ANDA$<>"D"THEN820
830 DV=1-7*(A$="D"):IFDV=8THENF$="0:"+F$
840 T$=F$:ZK=PEEK(50)+256*PEEK(51)-LEN(T$):POKE219
    ,ZK/256
841 POKE218,ZK-PEEK(219)*256:POKE209,LEN(T$)
845 POKE210,1:POKE211,0:POKE212,DV
850 POKE157,0:SYS62294:REM USE 62242 FOR UPGRADE P
    ET 3.0
860 IF(191ANDST)THEN870
865 PRINT"{DOWN}DONE.":GOTO310
870 PRINT"{DOWN}ERROR ON LOAD.{2 SPACES}TRY AGAIN.
    {DOWN}":IFDV_E=1THEN800
880 OPEN15,8,15:INPUT#15,E1$,E2$:PRINTE1$;E2$:CLOS
    E15:GOTO800
1000 REM BUZZER
1001 POKE59467,16:POKE59466,129:POKE59464,255
1003 FORT=200TO250:POKE59466,T:NEXT:POKE59467,0:RE
     TURN
2000 REM BELL SOUND
2001 POKE59467,16:POKE59466,51:POKE59464,100
2003 FORT=1TO50:NEXT:POKE59467,0:RETURN
3000 PRINT"{RVS}NOT ZERO PAGE, SCREEN OR ROM":GOTO
     1000


Program C-4. Atari MLX

Refer to Appendix E "How to Type In BASIC Programs" before entering this program.

100 GRAPHICS 0:DL=PEEK(560)+256*PEEK(561)+4:
    POKE DL-1,71:POKE DL+2,6
110 POSITION 8.0:? "MLX":POSITION 23,0:? "
    ":POKE 710,0:7
120 ? "Starting Address";:INPUT BEG:? " End
    ing Address";:INPUT FIN:? "Run/Init Addr
    ess";:INPUT STARTADR
130 DIM A(6),BUFFER$(FIN-BEG+127),T$(20),F$(
    20),CIO$(7),SECTOR$(128),DSKINV$(6)
140 OPEN #1,4,0,"K:":? :? ,"ape or isk:";
150 BUFFER=CHR$(0):BUFFER$(FIN-BEG+30)=BUFF
    ERA:BUFFER$(2)=BUFFER$:SECTOR$=BUFFER$
160 ADDR=BEG:CIO$="hhh":CIO$(4)=CHR$(170):CI
    O$(5)="LV":CIO$(7)=CHR$(228)
170 GET #1,MEDIA:IF MEDIAL>84 AND MEDIA<>68
    THEN 170
180 ? CHR$(MEDIA):? :IF MEDIA<>ASC("T") THEN
    BUFFER$="":GOTO 250
190 BEG=BEG-24:BUFFER$=CHR$(0):BUFFER$(2)=CH
    R$((FIN-BEG+127)/128)
200 H=INT(BEG/256):L=BEG-H*256:BUFFER$(3)=CH
    R$(L):BUFFER$(4)=CHR$(H)
210 PINIT=BEG+B:H=INT(PINIT/256):L=PINIT-H*2
    56:BUFFER$(5)=CHR$(L):BUFFER$(6)=CHR$(H)
220 FOR I=7 TO 24:READ A:BUFFER$(I)=CHR$(A):
    NEXT I:DATA 24,96,169,60,141,2,211,169,0
    ,133,10,169,0,133,11,76,0,0
230 H=INT(STARTADR/256):L=STARTADR-H*256:BUF
    FER$(15)=CHR$(L):BUFFER$(19)=CHR$(H)
240 BUFFER$(23)=CHR$(L):BUFFER$(24)=CHR$(H)
250 IF MEDIA<>ASC("D") THEN 360
260 ? :? "Boot isk or Binary ile:";
270 GET #1,DTYPE:IF DTYPE<>68 AND DTYPE<>70
    THEN 270
280 ? CHR$(DTYPE):IF DTYPE=70 THEN 360
290 BEG=BEG-30:BUFFER$=CHR$(0):BUFFER$(2)=CH
    R$((FIN-BEG+127)/128)
300 H=INT(BEG/256):L=BEG-H*256:BUFFER$(3)=CH
    R$(L):BUFFER$(4)=CHR$(H)
310 PINIT=STARTADR:H=INT(PINIT/256):L=PINIT-
    H*256:BUFFER$(5)=CHR$(L):BUFFER$(6)=CHR$
    (H)
320 RESTORE 330:FOR I=7 TO 30:READ A:BUFFER$
    (I)=CHR$(A):NEXT I
330 DATA 169,0,141,231,2,133,14,169,0,141,23
    2,2,133,15,169,0,133,10,169,0,133,11,24,
    96
340 H=INT(BEG/256):L=BEG-H*256:BUFFER$(B)=CH
    R$(L):BUFFER$(15)=CHR$(H)
350 H=INT(STARTADR/256):L=STARTADR-H*256:BUF
    FER$(22)=CHR$(L):BUFFER$(26)=CHR$(H)
360 GRAPHICS 0:POKE 712,10:POKE 710,10:POKE
    709,2
370 ? ADDR;":"::FOR J=1 TO 6
380 GOSUB 570:IF N=-1 THEN J=J-1:GOTO 380
390 IF N=-19 THEN 720
400 IF N=-12 THEN LET READ=I:GOTO 720
410 TRAP 410:IF N=-14 THEN ? :? "New Address
    ";:INPUT ADDR:? :GOTO 370
420 TRAP 32767:IF N<>-4 THEN 480
430 TRAP 430:? :? "Display:From";:INPUT F:?
    ,"To";:INPUT T:TRAP 32767
440 IF F<BEG OR F>FIN OR T<BEG OR T>FIN OR T
    <F THEN ? CHR$(253);"At least ";BEG;", N
    of More Than ";FIN:GOTO 430
450 FOR I=F TO T STEP 6:? :? I;":";:FOR K=0
    TO 5:N=PEEK(ADR(BUFFER$)+I+K-BEG):T$="00
    0":T$(4-LEN(STR$(N)))=STR$(N)
460 IF PEEK(764)<255 THEN GET #1,A:POP :POP
    :? :GOTO 370
470 ? T$;",";:NEXT K::? CHR$(126);:NEXT I:? .
    ? :GOTO 370
480 IF N<0 THEN ? :GOTO 370
490 A(J)=N:NEXT J
500 CKSUM=ADDR-INT(ADDR/256)*256:FOR 1=1 TO
    6:CKSUM=CKSUM+A(I):CKSUM=CKSUM-256*(CKSU
    M>255):NEXT I
510 RF=128:SOUND 0,200,12,8:GOSUB 570:SOUND
    0,0,0,0:RF=0:? CHR$(126)
520 IF N<>CKSUM THEN ? :? "Incorrect";CHR$(2
    53);:? :GOTO 370
530 FOR W=15 TO 0 STEP -1:SOUND 0,50.10,W:NE
    XT W
540 FOR I=1 TO 6:POKE ADR(BUFFER$)+ADDR-BEG+
    I-1,A(I):NEXT I
550 ADDR=ADDR+6:IF ADDR<=FIN THEN 370
560 GOTO 710
570 N=0:Z=0
580 GET #1,A:IF A=155 OR A=44 OR A=32 THEN 6
    70
590 IF A<32 THEN N=-A:RETURN
600 IF A<>126 THEN 630
610 GOSUB 690:IF I=1 AND T=44 THEN N=-1:? CH
    R$(126);:GOTO 690
620 GOTO 570
630 IF A<48 OR A>57 THEN 580
640 ? CHR$(A+RF);:N=N*10+A-48
650 IF N>255 THEN ? CHR$(253);:A=126:GOTO 60
    0
660 Z=Z+1:IF Z<3 THEN 580
670 IF Z=0 THEN ? CHR$(253);:GOTO 570
680 ? ",";:RETURN
690 POKE 752,1:FOR I=1 TO 3:? CHR$(30);:GET
    #6,T:IF T<>44 AND T<>58 THEN ? CHR$(A);:
    NEXT I
700 POKE 752,0:? " ";CHR$(126);:RETURN
710 GRAPHICS 0:POKE 710,26:POKE 712,26:POKE
    709,2
720 IF MEDIA=ASC("T") THEN 890
730 REM
740 IF READ THEN ? :? "Load File":?
750 IF DTYPE<>ASC("F") THEN 1040
760 ? :? "Enter AUTORUN.SYS for automatic us
    e":? :? "Enter filename":INPUT T$
770 F$=T$:IF LEN(T$)>2 THEN IF T$(1,2)<>"D:"
    THEN F$="D:":F$(3)=T$
780 TRAP 870:CLOSE #2:OPEN #2,8-4*READ,O,F$:
    ? :? "Working..."
790 IF READ THEN FOR I=1 TO 6:GET #2,A:NEXT
    I:GOTO 820
800 PUT #2,255:PUT #2,255
810 H=INT(BEG/256):L=BEG-H*256:PUT #2,L:PUT
    #2.H:H=INT(FIN/256):L=FIN-H*256:PUT #2,L
    :PUT #2,H
820 GOSUB 970:IF PEEK(195)>l THEN 870
830 IF STARTADR=0 OR READ THEN 850
840 PUT #2,224:PUT #2,2:PUT #2,225:PUT #2,2:
    H=INT(STARTADR/256):L=STARTADR-H*256:PUT
    #2,L:PUT #2,H
850 TRAP 32767:CLOSE #2:? "Finished.":IF REA
    D THEN ? :? :LET READ=0:GOTO 360
860 END
870 ? "Error ":PEEK(195);" trying to access"
    :? F$:CLOSE #2:? :GOTO 760
880 REM
890 IF READ THEN ? :? "Read Tape"
900 ? :? :? "Insert, Rewind Tape.":? "Press
    PLAY ";:IF NOT READ THEN ? "& RECORD"
910 ? :? "Press when ready:";
920 TRAP 960:CLOSE #2:OPEN #2,8-4*READ,128,"
    C:":? :? "Working..."
930 GOSUB 970:IF PEEK(195)>1 THEN 960
940 CLOSE #2:TRAP 32767:? "Finished.":? :? :
    IF READ THEN LET READ=0:GOTO 360
950 END
960 ? :? "Error ";PEEK(195);" when reading/w
    riting boot tape":? :CLOSE #2:GOTO 890
970 REM
   
980 X=32:REM File#2,$20
990 ICCOM=834:ICBADR=836:ICBLEN=840:ICSTAT=8
    35
1000 H=INT(ADR(BUFFER$)/256):L=ADR(BUFFER$)-
     H*256:POKE ICBADR+X,L:POKE ICBADR+X+1,H
1010 L=FIN-PEG+I:H=INT(L/256):L=L-H*256:POKE
      ICBLEN+X,L:POKE ICBLEN+X+1,H
1020 POKE ICCOM+X,11-4*READ:A=USR(ADR(CIO$),
     X)
1030 POKE 195,PEEK(ICSTAT):RETURN
1040 REM
1050 IF READ THEN 1100
1060 ? :? "Format Disk In Drive 1? (Y/N):";
1070 GET #1,A:IF A<>78 AND A<>89 THEN 1070
1080 ? CHR$(A):IF A=78 THEN 1100
1090 ? :? "Formatting...":XIO 254,#2,0,0."D:
     ":? "Format Complete":?
1100 NR=INT((FIN-BEG+127)/128):BUFFER$(FIN-B
     EG+2)=CHR$(0):IF READ THEN ? "Reading..
     .":GOTO 1120
1110 ? "Writing..."
1120 FOR I=1 TO NR:S=I
1130 IF READ THEN GOSUB 1220:BUFFER$(I*128-1
     27)=SECTOR$:GOTO 1160
1140 SECTOR$=BUFFER$(I*128-127)
1150 GOSUB 1220
1160 IF PEEK(DSTATS)<>l THEN 1200
1170 NEXT I
1180 IF NOT READ THEN END
1190 ? :? :LET READ=0:GOTO 360
1200 ? "Error on disk access.":? "May need f
     ormatting.":GOTO 1040
1210 REM
1220 REM
1230 REM Drive ONE
1240 REM Pass buffer in SECTOR$
1250 REM sector # in variable S
1260 REM READ=1 for read,
1270 REM READ=0 for write
1280 BASE=3*256
1290 DUNIT=BASE+1:DCOMND=BASE+2:DSTATS=BASE+
     3
1300 DBUFLO=BASE+4:DBUFHI=BASE+5
1310 DBYTLO=BASE+8:DBYTHI=BASE+9
1320 DAUXI=BASE+10:DAUX2=BASE+11
1330 REM DIM DSKINV$(4)
1340 DSKINV$="hLS":DSKINV$(4)=CHR$(228)
1350 POKE DUNIT,1:A=ADR(SECTOR$):H=INT(A/256
     ):L=A-256*H
1360 POKE DBUFHI,H
1370 POKE DBUFLO,L
1380 POKE DCOMND,87-5*READ
1390 POKE DAUX2,INT(S/256):POKE DAUXI,S-PEEK
     (DAUX2)*256
1400 A=USR(ADR(DSKINV$))
1410 RETURN


Return to Table of Contents | Previous Chapter | Next Chapter