Announcement

Collapse

Forum Rules and Etiquette

Our mission ...

This forum is part of our mission to promote the preservation of vintage computers through education and outreach. (In real life we also run events and have a museum.) We encourage you to join us, participate, share your knowledge, and enjoy.

This forum has been around in this format for over 15 years. These rules and guidelines help us maintain a healthy and active community, and we moderate the forum to keep things on track. Please familiarize yourself with these rules and guidelines.


Rule 1: Remain civil and respectful

There are several hundred people who actively participate here. People come from all different backgrounds and will have different ways of seeing things. You will not agree with everything you read here. Back-and-forth discussions are fine but do not cross the line into rude or disrespectful behavior.

Conduct yourself as you would at any other place where people come together in person to discuss their hobby. If you wouldn't say something to somebody in person, then you probably should not be writing it here.

This should be obvious but, just in case: profanity, threats, slurs against any group (sexual, racial, gender, etc.) will not be tolerated.


Rule 2: Stay close to the original topic being discussed
  • If you are starting a new thread choose a reasonable sub-forum to start your thread. (If you choose incorrectly don't worry, we can fix that.)
  • If you are responding to a thread, stay on topic - the original poster was trying to achieve something. You can always start a new thread instead of potentially "hijacking" an existing thread.



Rule 3: Contribute something meaningful

To put things in engineering terms, we value a high signal to noise ratio. Coming here should not be a waste of time.
  • This is not a chat room. If you are taking less than 30 seconds to make a post then you are probably doing something wrong. A post should be on topic, clear, and contribute something meaningful to the discussion. If people read your posts and feel that their time as been wasted, they will stop reading your posts. Worse yet, they will stop visiting and we'll lose their experience and contributions.
  • Do not bump threads.
  • Do not "necro-post" unless you are following up to a specific person on a specific thread. And even then, that person may have moved on. Just start a new thread for your related topic.
  • Use the Private Message system for posts that are targeted at a specific person.


Rule 4: "PM Sent!" messages (or, how to use the Private Message system)

This forum has a private message feature that we want people to use for messages that are not of general interest to other members.

In short, if you are going to reply to a thread and that reply is targeted to a specific individual and not of interest to anybody else (either now or in the future) then send a private message instead.

Here are some obvious examples of when you should not reply to a thread and use the PM system instead:
  • "PM Sent!": Do not tell the rest of us that you sent a PM ... the forum software will tell the other person that they have a PM waiting.
  • "How much is shipping to ....": This is a very specific and directed question that is not of interest to anybody else.


Why do we have this policy? Sending a "PM Sent!" type message basically wastes everybody else's time by making them having to scroll past a post in a thread that looks to be updated, when the update is not meaningful. And the person you are sending the PM to will be notified by the forum software that they have a message waiting for them. Look up at the top near the right edge where it says 'Notifications' ... if you have a PM waiting, it will tell you there.

Rule 5: Copyright and other legal issues

We are here to discuss vintage computing, so discussing software, books, and other intellectual property that is on-topic is fine. We don't want people using these forums to discuss or enable copyright violations or other things that are against the law; whether you agree with the law or not is irrelevant. Do not use our resources for something that is legally or morally questionable.

Our discussions here generally fall under "fair use." Telling people how to pirate a software title is an example of something that is not allowable here.


Reporting problematic posts

If you see spam, a wildly off-topic post, or something abusive or illegal please report the thread by clicking on the "Report Post" icon. (It looks like an exclamation point in a triangle and it is available under every post.) This send a notification to all of the moderators, so somebody will see it and deal with it.

If you are unsure you may consider sending a private message to a moderator instead.


New user moderation

New users are directly moderated so that we can weed spammers out early. This means that for your first 10 posts you will have some delay before they are seen. We understand this can be disruptive to the flow of conversation and we try to keep up with our new user moderation duties to avoid undue inconvenience. Please do not make duplicate posts, extra posts to bump your post count, or ask the moderators to expedite this process; 10 moderated posts will go by quickly.

New users also have a smaller personal message inbox limit and are rate limited when sending PMs to other users.


Other suggestions
  • Use Google, books, or other definitive sources. There is a lot of information out there.
  • Don't make people guess at what you are trying to say; we are not mind readers. Be clear and concise.
  • Spelling and grammar are not rated, but they do make a post easier to read.
See more
See less

Palo Alto Tiny Basic: Download

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Palo Alto Tiny Basic: Download

    Hi,

    For the last couple of months I have been working with the assembly source code for Palo Alto Tiny Basic (PATB) for the X86 CPU family. The PATB has a long history going back to Dr. Dobb's Journal in the 1970's. The code was an open source alternative for hobbyists to get into the game programming on the cheap.

    After the initial publication of the source code a myriad of tweaks, changes and ports appeared. My interest in the 8088 CPU in the IBM 5150 PC and the PC-RETRO (an exact clone) prompted me to investigate creating a version of PATB that could work as a stand-alone boot, much like the CASSETTE BASIC provided by IBM, but with the important difference that we have the source code to modify for our projects and applications.

    My coding project began with a version of PATB released by Michael Sullivan for the 8086. His version used DOS INT 21H for Input and Output services. My project replaced those INT 21H calls with calls directly to the BIOS services. I had help with this project, and it was my first major experience with Assembly Language programming.

    Right now I am at the point that I want to post an early Beta version of the progress to date, for people to play with. I have managed to get this code to the point that I can burn an EPROM for socket U29 in the 5150 PC and have PATB boot. I have created a compressed zip file of the files and posted it here:

    http://www.mtmscientific.com/PATB.zip

    Here is a listing from the README file in the ZIP file package:

    Here is an explanation of the files in this compressed folder.

    PATB.JPG is a photo of the cover of the Interface Age Book
    PATBS-SM.JPG is the same photo in a smaller format.

    PATB.PDF is a scan of the original source code for Palo Alto
    Tiny Basic, from the Interface Age book.

    PATB-MTM.ASM is the source code for the MTM version of PATB.
    The source code will compile with NASM. Note that no DOS
    interrupts are used in the code.

    PATB-MTM.COM is a compiled version of the MTM version of PATB.
    This version will run on any PC compatible computer. A good way
    to start playing with the program...

    PATB-MAN.TXT is a short manual about how to use PATB. Note
    that the main working difference is how to SAVE and LOAD files.
    Note: This would really benefit from a good file system, and
    coding modifications to work with larger files.

    PATB-ROM.BIN is a binary file, that if burned and placed in
    IBM PC socket U-29 will boot PATB instead of CASSETTE BASIC.
    This code will fit in a 27128 EPROM without modification, by
    using an adapter: http://www.minuszerodegrees.net/5150_u33.htm

    RELOC.TXT is the source code for the relocation code in the ROM.
    This was compiled using DEBUG. Simply change source and destination
    addresses as your application warrants.

    README.TXT is this file.

    This code has not been extensively error checked. I would appreciate
    any and all help to improve the project. Thank You!

    PS. PATB expects commands in upper caps only. Here are a few examples:

    PRINT "HELLO"
    PRINT 2+2
    etc.

    Michael

    #2
    Excellent! It works well for me running the .COM version. It also seemed to take lowercase commands just fine, btw. I'd like to try it on an EEPROM, but I'll need to find a couple blank ones. Shouldn't I only need one? I know it's a 16 KB ROM file, but if I look at it in a hex editor, it's all nulls until offset 8192. I did try it in my emulator, loading it at F600:0000 but the generic XT BIOS doesn't seem to recognize it as ROM BASIC. I also tried jumping to F600:0000 from DOS, but it just hangs.
    sigpic

    Comment


      #3
      Originally posted by mmruzek View Post
      Here is an explanation of the files in this compressed folder.
      My suggestion is to include a test suite of PATB BASIC programs (or single program) that can be used to test and verify the interpreter.
      Offering a bounty for:
      - A working Sanyo MBC-775 or Logabax 1600
      - Music Construction Set, IBM Music Feature edition (has red sticker on front stating IBM Music Feature)

      Comment


        #4
        Going through the code -- a couple observations...

        Int10h doesn't corrupt BX, CX or DX -- since you're not changing CX or DX inside chrOut, you don't need to push/pop them. Same for int16h which preserves everything except AX and FLAGS.

        This part:
        Code:
        ps1:
         mov si,dx
         lodsb           ;get a char
         lahf            ;preserve flags
         inc dx
         sahf            ;restore flags
         cmp al,ch       ;same as old a?
         jnz ps2         ;yes, return
         ret
        If you are doing a immediate compare, which changes all the flags, why are you bothering to store the flags in AH and then restore them?!?

        I would also give some serious thought to switching how strings work, possibly for pascal style (length first) -- I realize this is an early port, but that's something I'd address right quick. The speed increases and simpler code would more than make up for the increase in data sizes.

        Also... it might really help if you stopped using such needlessly cryptic labels
        From time to time the accessibility of a website must be refreshed with the blood of owners and designers. It is its natural manure.
        CUTCODEDOWN.COM

        Comment


          #5
          As it is currently written the random number generator will begin
          failing between 4 and 5 minutes after a cold boot...

          Code:
           mov ax, 40h
           mov ds, ax
           mov ax, [06ch]
           mov dl, 20
           div dl
          Once the timer (40:6c) reaches 0x1400 (20*256) ticks, the quotient (AL)
          will overflow and generate a divide error (interrupt 0).

          Also you are seeding the prng with the timer on each call to rnd(), thus
          subsequent calls to rnd() will return identical values unless the timer
          has advanced (not the desired behaviour I assume!).


          typo: PATB-MAN.TXT line 276 mached->matched

          Comment


            #6
            Good catch b44ccd21!!!

            I'd suggest simply doing

            and ax,$03FF

            Before the divide, neutering the result to 0..1023 and as such the max divide result of AL 51 AH 3. I usually restrict the values that way any time I know the divisor -- though in this case the impact on the RNG might be unexpected. Might be time to lift a better RNG from some existing library.
            From time to time the accessibility of a website must be refreshed with the blood of owners and designers. It is its natural manure.
            CUTCODEDOWN.COM

            Comment


              #7
              Originally posted by deathshadow View Post

              I'd suggest simply doing

              and ax,$03FF

              Before the divide
              true; although 0000111111111111b may give a wider range.

              Originally posted by deathshadow View Post
              Might be time to lift a better RNG from some existing library.
              The algorithm used by borland c for dos is fairly lightweight and maybe
              that compatability would be a plus?
              Code:
              // ----------------------------------------------------------------------------
              struct PRNG
              {
                long s;
                long m;
                long i;
              
                int  g( void ) { return( ( ( s = s * m + i  ) >> 0x0010 ) & 0x7fff ); }
              };
              // ----------------------------------------------------------------------------
              PRNG bcc = { 0x00000001, 0x015a4e35, 0x00000001 };
              PRNG msc = { 0x00000001, 0x000343fd, 0x00269ec3 };
              // ----------------------------------------------------------------------------
              // ----------------------------------------------------------------------------
              #include <iostream.h>
              #include <stdlib.h>
              
              typedef  unsigned int    WORD;
              #define  PTR(s,o)        ((void _seg*)(s)+(void near*)(o))
              #define  WORD_PTR(s,o)   ((WORD*)PTR(s,o))
              
              void main( int, char*[] )
              {
                bcc.s = WORD_PTR( 0x0040, 0x006c )[0];
                srand( bcc.s );
              
                for( int i = 0; i < 0x0010; i++ )
                {
                  cout << bcc.g() << " " << rand() << endl;
                }
              }
              // ----------------------------------------------------------------------------
              however for "tiny" basic perhaps an lfsr would suffice?( nods to trixter... ).
              Code:
              G goto10_lfsr/13_inescapable         // d1eed6730233f404ddcd29ebf3
              G                                    //
              G in:    sp       0xfffe             // .com entry
              G        si       0x0100             // ; sp = polynomial, si = seed
              G                                    //
              Z .goto10_lfsr_prng:                 //
              G                                    //
              Q %      shr      si, 0x01           // galois_lfsr( 0xfffe, 0x0100 )
              Q %      db       0xd6               // : (salc) cf->al [0x00,0xff] for plot
              Q %      jnc      .goto10_lfsr_plot  // : pseudo-random bit, period 0x12d4
              Q %      xor      si, sp             // : sp = polynomial, si = state
              G                                    // '
              Z .goto10_lfsr_plot:                 // plot
              G                                    // :
              Q %      add      al, 0xdd           // : al = [0xdc,0xdd] 
              Q %      int      0x29               // ' dos::fast_console_output(al)
              Q %      in       al, 0x60           // kb
              Q %      dec      ax                 // : escape?
              Q %      jnz      .goto10_lfsr_prng  // '
              Q %      retn                        // exit
              NEC: salc->sbb al, al (+1b)

              obviously for use in PATB, one would use a polynomial that generates a
              maximal length sequence so a modulo of the lfsr's state would give
              appropriate ranged return values for RND().

              Comment


                #8
                Yeah, there are many ways to skin this cat. I've played with this before:

                Code:
                    
                        mov ax, word ptr randseed[2]
                        mov dx, word ptr randseed[0]
                        mov bx, ax
                        mov cx, dx
                        shl cx, 3
                        shr bh, 4
                        or cl, bh
                        xor dx, cx
                        not dx
                        shl dx, 1
                        rcl ax, 1
                        shr dx, 1
                        mov word ptr randseed[0], ax
                        mov word ptr randseed[2], dx
                This claims 2^31-1 repeatability but I've never verified it.

                Another way, if you don't care too much about periodicity and just want small fast results:

                Code:
                        mov     ax,seed
                        add     ax,9248h        ;; 1001001001001000b (visual rep)
                        ror     ax,1
                        ror     ax,1
                        ror     ax,1
                        mov     seed,ax
                ...which seems to have a good spread. Yet another:

                Code:
                    mov cl,121 ; initial seed
                ...
                    rol cx,cl ;this is the
                    add cx,7  ;random function
                ...if you want something super-small and don't care about quality.

                BTW definitely never, ever use the "SALC" undocumented opcode in 8088-era code, since it is very, very common to have the 8088/8086 replaced with an NEC V20/v30 where this breaks. Always use SBB AL,AL instead.
                Offering a bounty for:
                - A working Sanyo MBC-775 or Logabax 1600
                - Music Construction Set, IBM Music Feature edition (has red sticker on front stating IBM Music Feature)

                Comment


                  #9
                  Originally posted by Trixter View Post
                  BTW definitely never, ever use the "SALC" undocumented opcode in 8088-era code, since it is very, very common to have the 8088/8086 replaced with an NEC V20/v30 where this breaks. Always use SBB AL,AL instead.
                  heh... preaching to the converted my friend ( I did mention NEC:
                  salc->sbb al, al in my original post... ).

                  Are there any other NEC related pitfalls one needs to be aware of?

                  I seem to remember the undocumented non-decimal form of the AAM opcode
                  being unsupported by the V30 (amstrad shipped some of its PPC's with
                  V30s, some with 8086s).

                  Have you verified AAM's behaviour on the NEC V-series?, If so, do you
                  know of any trivial workarounds as it frequently crops up in hex to
                  ascii code.

                  vide:

                  Code:
                  G
                  G #############################################################################
                  G
                  Z .h_dword:                     // IN: dx:ax
                  G                               //
                  Q %      call     .h_dword_hi   //
                  G                               //
                  Z .h_dword_hi:                  //
                  G                               //
                  Q %      xchg     ax, dx        //
                  G
                  G #############################################################################
                  G
                  Z .h_word:                      // IN: ax
                  G                               //
                  Q %      push     ax            //
                  Q %      xchg     ah, al        //
                  Q %      call     .h_byte       //
                  Q %      pop      ax            //
                  G
                  G #############################################################################
                  G
                  Z .h_byte:                      // IN: al
                  G                               //
                  Q %      db       0xd4, 0x10    // aam 0x10: al -> nibbles in ah/al
                  Q %      call     .h_nibble     //
                  G                               //
                  Z .h_nibble:                    //
                  G                               //
                  Q %      xchg     ah, al        //
                  Q %      cmp      al, 0x0a      //
                  Q %      sbb      al, 0x69      //
                  Q %      das                    //
                  G                               //
                  Q %      int      0x29          // DOS::fast_console_output
                  Q %      retn                   //
                  G
                  G #############################################################################
                  G
                  :
                  :
                  :
                  Q %      mov      al, 0x12      //
                  Q %      call     .h_byte       //
                  G                               //
                  Q %      mov      ax, 0x1234    //
                  Q %      call     .h_word       //
                  G                               //
                  Q %      mov      dx, 0x1234    //
                  Q %      mov      ax, 0x5678    //
                  Q %      call     .h_dword      //
                  :
                  :
                  :
                  replacing
                  Code:
                  Q %      db       0xd4, 0x10    // aam 0x10: al -> nibbles in ah/al 2
                  Q %      call     .h_nibble     //                                  3
                  G                               //
                  Z .h_nibble:                    //
                  G                               //
                  Q %      xchg     ah, al        //                                  2
                  with
                  Code:
                  Q %      mov      cl, 0x04      // ax == ????????hhhhllll           2
                  Q %      ror      ax, cl        // ax == llll????????hhhh           2
                  Q %      and      al, 0x0f      // ax == llll????0000hhhh           2
                  Q %      shr      ah, cl        // ax == 0000llll0000hhhh           2
                  Q %      call     .h_nibble     //                                  3
                  Q %      xchg     ah, al        //                                  2
                  G                               //
                  Z .h_nibble:                    //
                  G                               //
                  works, but at +6bytes and clobbering CL, it leaves somewhat of a nasty
                  taste in the mouth...

                  Comment


                    #10
                    Originally posted by b44ccd21 View Post
                    heh... preaching to the converted my friend ( I did mention NEC:
                    salc->sbb al, al in my original post... ).
                    I know, I was reiterating the point in case someone thought they should do it anyway. You can do it on NEC v20/v30 but on those chips it aliases to XLAT so the program won't crash but it certainly won't work properly.

                    Are there any other NEC related pitfalls one needs to be aware of?
                    Don't use the AAM/AAD supply-your-own-operand trick as it doesn't work. Perform a full mul/div or, if the values are small enough, use a lookup table. There is a lot of AAM in hex conversion code but, really, burning up 16 bytes for a lookup table is not horrible and XLAT is faster anyway.

                    POP CS works on 8088/8086 but is a prefix on NEC for extended NEC opcodes, so don't use it. 80186 and later POP CS is invalid so really don't use it.

                    I think that's it.

                    On the flip side, there are some neat NEC opcodes I wish I had on 808x, such as the REP prefixes "repeat while carry" and "repeat while no carry", and the ability to rotate a byte-sized reg by 4 without needing CL=4. And of course NEC v20/v30 can do shift and rotate by more than 1 (ie. SHL AX,5) just like 8018x. I read somewhere that IBM PC DOS 7.x has NEC detection and will install some NEC-specific code if found, but I don't know to what extent.
                    Offering a bounty for:
                    - A working Sanyo MBC-775 or Logabax 1600
                    - Music Construction Set, IBM Music Feature edition (has red sticker on front stating IBM Music Feature)

                    Comment


                      #11
                      Originally posted by Trixter View Post
                      BTW definitely never, ever use the "SALC" undocumented opcode in 8088-era code, since it is very, very common to have the 8088/8086 replaced with an NEC V20/v30 where this breaks. Always use SBB AL,AL instead.
                      Be careful--the SALC does not affect any flags, while SBB AL,AL does. So check the preceding and following code to see if the original depends upon a flag being preserved across the SALC.
                      Reach me: vcfblackhole _at_ protonmail dot com.

                      Comment


                        #12
                        Sorry to necropost, but this was referenced in another thread: mmruzek, did you ever review some of the bugs (ie. random number generator will cause a divide by zero) mention in this thread and come out with a new version of your 8086 PATB?
                        Offering a bounty for:
                        - A working Sanyo MBC-775 or Logabax 1600
                        - Music Construction Set, IBM Music Feature edition (has red sticker on front stating IBM Music Feature)

                        Comment


                          #13
                          I have a text based "Star Treck" game for the PA BT, someplace. If interested, let me know and I'll look for it.
                          Dwight

                          Comment


                            #14
                            Originally posted by Trixter View Post
                            Sorry to necropost, but this was referenced in another thread: mmruzek, did you ever review some of the bugs (ie. random number generator will cause a divide by zero) mention in this thread and come out with a new version of your 8086 PATB?
                            Hi! I regret that I have not had time to make any updates on this project. The posted version is the most recent. PATB is really an interesting part of the early years of computer history. I posted a link in the Publications part of the forum to scans of early Dr. Dobb's journals, if anyone cares to read more. My original thinking was that PATB burned to ROM would be a nice addition to the PC-Retro Kits that I offer. If anyone improves the code please advise. Thanks! Michael

                            Comment


                              #15
                              One other thought, if you used the PATB listing off the web that ran on the Poly88, it has the ability to extend the instruction set. I'd added a PEEK, POKE and a SAVE. Since i used this on the Poly 88, I used the monitor's load to read the files, from cassette. If it is similar, there is a part after reset that would sample a value in memory. If it were the right value, it would attach the code to the instruction decode.
                              Although, the code part might not be of much use, being 8080 code, the part that added instruction might be of some use. As I recall, the instructions were in two types. One was one that returned a value and the other was a type that took parameters. This required adding to two different parts of the instruction decode.
                              Dwight
                              Last edited by Dwight Elvey; May 8, 2018, 02:43 PM.

                              Comment

                              Working...
                              X