Tagged: C128 Toggle Comment Threads | Keyboard Shortcuts

  • Jay Versluis 10:31 am on May 10, 2018 Permalink | Reply
    Tags: C128,   

    Categories: Commodore ( 41 )   

    How to enter C64 Mode on a Commodore 128 

    The Commodore 128 was marketed as being “three computers in one”. I guess technically they were correct when they made that statement. Although I’m very find of the native 128 mode, the system saw its uses mostly as a games machines in C64 mode. I don’t recall anybody ever looking at CP/M mode longer than half an hour (if that).

    There are three ways to put the C128 into C64 mode. Two of which I always knew about, ever since my friend Frank Jagow bought himself a whole C128 system from his paper route money inΒ 1986. But the third option’ve only recently learnt about – after over 30 years of being a C128 fanboy. How exciting!

    Here are all three options. (More …)





     
  • Jay Versluis 9:35 am on May 8, 2018 Permalink | Reply
    Tags: C128, ,   

    Categories: Commodore ( 41 ), Screencast ( 87 )   

    How to write a text input routine in Commodore BASIC 

    In this screencast I’ll show you how to write your own INPUT routine in Commodore BASIC. This comes in handy when you want to reject certain keys from being used when asking users for keyboard input. In my example I’m going to allow all alpha characters (A-Z), as well as SPACE, RETURN and the DELETE key.

    Here’s the code:





     
  • Jay Versluis 3:44 pm on April 18, 2018 Permalink | Reply
    Tags: C128, ,   

    Categories: Commodore ( 41 )   

    Flashing Border Colors on the Commodore 128 in Machine Language 

    In this screencast I’ll show you how to create the iconic flashing borders on Commodore machines. Back in the day, when the system was loading, this was a nice way to indicate that the computer is busy doing something rather than being dead. I’ll show you the principle both in BASIC and in Machine Language on the C128. The VIC-II chip is the same on the C64 though, so this will also work on the Commodore 64.

    The same approach can be used on the Plus/4, however the addresses for the border and background colours are different (decimal 65305, or hex $FF19).

    The VIC-20 is another story, as the border and background colour are changed using the same address (decimal 36879, or hex $900F). This link may help though: http://www.sleepingelephant.com/ipw-web/bulletin/bb/viewtopic.php?t=5905

    As always, enjoy πŸ™‚





     
  • Jay Versluis 3:42 pm on April 17, 2018 Permalink | Reply
    Tags: , C128, ,   

    Categories: Commodore ( 41 )   

    Programmatic Loops in Commodore BASIC 

    In this screencast I’ll demonstrate how to use programmatic loops in Commodore BASIC.

    I’ll show you how to use the FOR/NEXT loop (available in all versions of Commodore BASIC), as well as the DO/WHILE loops (available on the Plus/4 and C128).

    Enjoy!





     
  • Jay Versluis 3:29 pm on April 16, 2018 Permalink | Reply
    Tags: , C128, ,   

    Categories: Commodore ( 41 )   

    Flow Control in Commodore BASIC 

    In this screencast I’ll explain the concept of Flow Control in Commodore BASIC. It’s kind of a video update of a post I did a while ago.

    In essence, it means that we can tell the programme to take a different route in the code depending on a condition that’s met. We’ll explore the IF/THEN and ON… GOTO/GOSUB statements (available on all versions of Commodore BASIC), as well as the expanded IF/THEN/ELSE version (available on the C128 and Plus/4 only).

    In addition, I’ll also show you how to use the BEGIN and BEND clauses that were introduced with the C128.





     
  • Jay Versluis 7:22 pm on April 13, 2018 Permalink | Reply
    Tags: C128,   

    Categories: Commodore ( 41 ), Screencast ( 87 )   

    Writing HELLO WORLD in Machine Language on the Commodore 128 

    The Commodore 128 has a built-in machine language monitor which makes it ideal for ML development. However, most (or pretty much all) documentation on this subject is geared towards the Commodore 64, making it slightly difficult to get a head start in writing ML code for the 128.

    Before I forget how to do it, here are a few pointers – courtesy of Jim Butterfield’s book “Machine Language – Expanded Edition”.

    Getting Started

    Let’s begin by typing MONITOR in C128 mode. It’ll take us to the machine language monitor. We’ll start our programme at $0B00. To begin assembling our code, we’ll type A 0B00 (A for Assemble), followed by these lines:

    LDX #$00
    LDA $0C10,X
    JSR $FFD2
    INX
    CPX #$2B
    BNE $0B02
    RTS

    The MONITOR will turn this text into the output you’ll see in the screenshot above (the lines starting with a . dot). Here’s what this code will do when called:

    First we’ll load the X register with a value of zero. We’ll use this register as a counter. In the next line we’ll load the accumulator with whatever is stored in address $0C10 plus whatever is stored in the X register. So if X has a value of zero, then the contents of $0C10 will be loaded. If X was 1, then the value in $0C11 would be loaded, and so forth.

    We’re using this as ASCII representation of our text (Hello World in a box in this case). With JSR $FFD2 we’ll call a Kernal routine that prints a single character onto the screen. Now we’re incrementing X by one and ask if it’s 45 yet (CPX #$2D). This would indicate that we’ve printed all the characters we need. If that’s not the case, we’ll return to line 2 and keep printing. Otherwise, we’ll stop the programme.

    Storing ASCII characters

    You’d think it was possible to simply type in text in the MONITOR. But of course that would be too easy. Instead we need to grab one of those massive tables and hack in each character’s ASCII code in hex. How convenient!

    Type M 0C10 (or whichever location in memory you’d like to store your text string at) and overtype the numbers at the start of the line, each one representing a single byte of our ASCII text. At the end of each line you’ll see what those characters look like when converted.

    In my case it’s a total of 45 characters, beginning with a return, followed by the top of the box, HELLO WORLD, and the bottom of the box.

    Running from the MONITOR

    To start the programme from the monitor, we’ll type G F0B00. We’ll end up with a SYNTAX ERROR and back on the BASIC screen though due to the RTS command at the end of the listing. If we replace it with a BRK command instead, we’ll end up back in the MONITOR.

    The important thing to remember is the five digit addressing mode on the C128 (i.e. G for GO, followed by F0B00). Our programme starts at $0B00 in memory, but to make it run properly we’ll have to specify which BANK it should be called from. Anything other than BANK 0 or BANK 1 is fine, otherwise we won’t reach the print routine at $FFD2. In my example I’m choosing F, but E would work fine too (as we’ll see in a moment).

    Running from BASIC

    Type X to exit the monitor and go back into the land of BASIC. First we’ll need to choose a BANK. We’ll have 16 to choose from (0 to 15), so perhaps let’s try BANK 15. Now we’ll need to type the start of our programme in decimal:

    BANK 15
    SYS 2816

    or we can use the DEC command to convert hex to decimal on the fly:

    BANK 15
    SYS DEC("0B00")

    Saving the programme

    From the MONITOR, we can save the programme using the S command. It needs to be followed by a name (in double quotes), followed by the drive number, memory start and memory end plus one byte – all separated by a comma. It’s probably easier to show than to write:

    S "HELLO WORLD",8,0B00,0C40

    We’re saving more bytes than strictly necessary here due to the large gap between our code and the beginning of the ASCII string. Our string could go up to $0C3F. The last byte in $0C40 is NOT saved to disk (or tape).

    We can do the same from BASIC using the BSAVE command (for Binary SAVE). The syntax is BSAVE “FILE NAME”, P1234 TO P5678. Sadly the DEC command doesn’t work inline with this command, which would make it extremely useful. We’ll have to convert the values into decimal manually instead.

    BSAVE "HELLO WORLD", P2816 TO P3136

    Loading the programme

    To bring our masterpiece back into the computer from the MONITOR, the L command works a treat:

    L "HELLO WORLD",8

    From BASIC we can load the programme the usual way, making sure we load it with ,DEVICE,1 at the end. This is to make sure it is loaded into the same memory it was saved from, rather than the start of BASIC:

    LOAD "HELLO WORLD",8,1

    Happy Assembling!





     
    • Iain 12:43 am on May 1, 2018 Permalink | Reply

      I always thought writing “hello world” would be that easy…

  • Jay Versluis 12:10 am on April 2, 2018 Permalink | Reply
    Tags: , C128, ,   

    Categories: Commodore ( 41 )   

    How to print Numbers as Columns in Commodore BASIC 

    In this video I’m demonstrating how to print numbers in evenly spaced columns in Commodore BASIC.

    On the C128 and the Plus/4 we can use a nifty little function called PRINT USING for this, with which we can format the output of any printed text or variable.

    On the C64 and VIC-20 that function doesn’t exist, so we’ll have to convert a numeric value into a string (using the STR$ function), and then determine how long our string is. Following that we’ll have to manually pad our string value with as many spaces as are required. (More …)





     
  • Jay Versluis 10:17 am on April 1, 2018 Permalink | Reply
    Tags: C128, , ,   

    Categories: Commodore ( 41 )   

    Sorting an Array on the Commodore 64 

    In this video I’ll demonstrate how to sort a numeric array on the Commodore 64. The same principle works for string arrays, and of course on all other Commodore BASIC computers.

    The technique I’m using here is called Bubble Sort: in effect we’re comparing the first two items in the array, and if the left one is larger than the right one, the values are swapped around. This loop continues until all items in the array have been compared and sorted (hence the smallest items “bubble” to the front of the array, much like the smallest bubbles in a soda float to the top first).

    Here’s the full code I’m building, including the lottery portion. The Bubble Sort code starts in line 200.

    10 x=rnd(-ti)
    20 for i=1 to 6
    30 rn=int(rnd(1)*49)+1
    40 for j=1 to i
    50 if n(j)=rn then 30
    60 next j
    70 n(i)=rn
    80 next i
    100 print:gosub 200
    110 for i=1 to 6
    120 print n(i);
    130 next
    140 print
    199 goto 20
    200 rem bubble sort
    210 for i=5 to 1 step -1
    220 for j=1 to i
    230 x=n(j):y=n(j+1)
    240 if x>y then n(j)=y:n(j+1)=x
    250 next:next
    299 return

    I’ve explained how to build the lottery generator in this code here: https://wpguru.co.uk/2018/03/how-to-generate-lottery-numbers-on-the-commodore-64/

    Happy retro hacking!





     
  • Jay Versluis 12:39 pm on March 31, 2018 Permalink | Reply
    Tags: C128, ,   

    Categories: Commodore ( 41 ), Screencast ( 87 )   

    How to generate Lottery Numbers on the Commodore 64 

    In this video I’ll demonstrate how to draw random lottery numbers on a Commodore 64. The secret sauce here is not only the RND function to generate random numbers, but also two loops inside each other that prevent the same number from coming up more than once.

    Here’s the lottery generator code:

    10 x=rnd(-ti)
    20 for i=1 to 6
    30 rn=int(rnd(1)*49)+1
    40 for j=1 to i
    50 if n(j)=rn then 30
    60 next j
    70 n(i)=rn
    80 next i
    100 print
    110 for i=1 to 6
    120 print n(i);
    130 next
    140 print
    199 end

    To adapt this listing to match your local lottery, change line 20 to the amount of numbers to be drawn from your pool (6 in my example), and change the value in line 30 to match the size of your pool (49 in my example).

    Any questions, please let me know below.

    Happy retro hacking!





     
  • Jay Versluis 11:43 am on March 14, 2018 Permalink | Reply
    Tags: C128, , , VIC-20   

    Categories: Commodore ( 41 )   

    String Operations on Commodore Computers 

    Commodore BASIC has some interesting and simple string functions built in. Three of them are self explanatory: LEN, LEFT$ and RIGHT$. But others, like the mysterious MID$ and INSTR functions, are a little tricker, and I can never remember how they works.

    So here’s a quick recap on how they all work.

    LEN (A$)

    Returns the length of any given string. For example,

    a$=”the cake is a lie”

    print len (a$)
    17

    returns 17, which is the number of characters in our string.

    LEFT$ (A$,X)

    The LEFT$ function takes the x left characters from a given string. Here’s an example:

    a$="one-two-three"
    
    print left$(a$,3)
    one

    We get “one”, because those are the 3 leftmost characters in our string a$.

    RIGHT$ (A$,X)

    Likewise, RIGHT$ takes the x right characters from any given string:

    a$="one-two-three"
    
    print right$(a$,5)
    three

    Here we get “three”, because those are the 5 right characters of a$.

    MID$ (A$,X,Y)

    MID$ is a little more complex. It takes x characters from a given string, starting at position y. Let’s look at our earlier example again:

    a$="one-two-three"
    
    print mid$(a$,5,3)
    two

    We get “two”, because those are the 3 characters, starting at position 5. The first position in all these string operations counts as one rather than zero.

    But did you know that MID$ can also be used to assign and replace different characters in a string? Consider this:

    mid$(a$,5,3)="ten"
    
    print a$
    one-ten-three

    Now we’ve replaced the 3 characters in our string with another string, starting at position 5.

    I had no idea it cold do that! All these string operations work in all variations of the Commodore BASIC, except for the MID$ assignment which only works on the Plus/4 and the C128.

     

    INSTR (A$, B$)

    On the Plus/4 and C128, we can even check if one string is contained in another and at which position this occurs. Consider this:

    a$="the cake is a lie"
    
    b$="cake"
    
    print instr(a$,b$)
     5

    In our example, INSTR returns 5 because “cake” has been found at position 5 of “the cake is a lie”.

    We can also specify a position from which the search shall be started like this:

    print instr(a$,b$,6)
     0

    Now INSTR returns 0 because “cake” has not been found beyond position 6 of our input string.





     
c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Reply
e
Edit
o
Show/Hide comments
t
Go to top
l
Go to login
h
Show/Hide help
shift + esc
Cancel