WAITing for BASIC on the Commodore 64

Sdílet
Vložit
  • čas přidán 31. 07. 2024
  • How can we make Commodore 64 BASIC pause for a specific time? We take a look at three techniques, including their strengths and weaknesses: 1) FOR/NEXT loops which are simple but somewhat inaccurate and not very CPU-accelerator-friendly, 2) polling the TIME variable which might be the best general approach, and 3) Using the esoteric WAIT command to watch particular bits in the C64's jiffy counter. Thanks to patron grymmjack for the question, and to Dr. Craig S. Bruce, Emily Christ, and Jarno Mielikäinen for their insight and help with the answers.
    To support 8-Bit Show And Tell:
    Become a patron: / 8bitshowandtell
    One-time donation: paypal.me/8BitShowAndTell
    2nd channel: / @8-bitshowandtell247
    End credits song is "Park Patrol" by Bedford Level Experiment. Check out the music video here: • Park Patrol - original...
    Index:
    0:00 Question: how to sleep/pause/wait in BASIC?
    0:23 1. FOR/NEXT loop
    7:18 Why not linear?
    11:55 2. Polling TI
    16:04 A bug in the TI technique
    20:50 3. WAIT 162,64
    24:26 Why not WAIT 162,60?
    29:50 Another WAIT approach
    30:59 Conclusion and thanks!
  • Věda a technologie

Komentáře • 176

  • @EmilOppelnBronikowski
    @EmilOppelnBronikowski Před 2 lety +20

    "It's terrible, but it works"
    This is my career in programming in one sentence.

    • @mikegarland4500
      @mikegarland4500 Před 11 měsíci

      hehe, I've got a linearly increasing set of POKEs that go up and down from a middle number, something that should be easy to translate over to FOR:NEXT loops but it's working perfectly now, and I really don't want to mess that up. 🙂

  • @grymmjack
    @grymmjack Před 2 lety +24

    Thanks Robin! This was exactly what I was hoping for. Really appreciate the extra time and effort you put in to answering the question as completely as you could!

  • @realzneo
    @realzneo Před 2 lety +10

    Hi Robin! Thanks for the video! Many years ago, when I was in school, I made a countdown timer on my TI calculator - to count down the time until our class was over.. It was based on loops, and showed minutes and seconds. It was very imprecise in the beginning, but I kept improving it - when I was bored in class. It got kind of accurate up to one hour!

  • @8BitNaptime
    @8BitNaptime Před 2 lety +5

    So they're like Gremlins, don't run the loop after midnight.

  • @cemmy410
    @cemmy410 Před 2 lety +5

    Ooooh, thank you so much for going back and looking at my question!

    • @8_Bit
      @8_Bit  Před 2 lety +2

      Thank you for pointing that problem out! That's a problem that can occur in many situations even in modern development so it's great to raise awareness of it.

  • @RiggieHeartland
    @RiggieHeartland Před 2 lety +2

    Simple and easy - and precise:
    10 INPUT W
    20 TI$="000000"
    30 IF TI/60

  • @Jake-23
    @Jake-23 Před 2 lety +3

    This is yet another great video! Thank you! Also the segment that touches on floating point number(s) normalization is fantastic.

  • @HoyVision
    @HoyVision Před 2 lety

    A user on one of my BBSes said I needed to come check out your channel. Thank you for your contributions to the C= community! :D

  • @aner_bda
    @aner_bda Před 2 lety +1

    It was really cool to see the walkthrough of each of these approaches. I immediately thought of the polling TI method, but seeing that bug was interesting. Great video.

  • @HAGSLAB
    @HAGSLAB Před 2 lety +1

    I love these videos. A lot of trial and error and multiple solutions to the same problem. This is how I remember getting started with programming. Just "messing" around like this. Great way of learning I think!

  • @MichaelDoornbos
    @MichaelDoornbos Před 2 lety +15

    These times are quite a bit different on a PAL machine. Through trial and error I was able to get them pretty close on a PAL machine.
    Also, just a clarification at 6:46: The Ultimate64 can switch anywhere between 1 and 48Mhz (also between PAL and NTSC on the fly), but the Ultimate 1541 (now called the Ultimate II+) does not have a CPU accelerator in it.
    21:31 The Toolkit: BASIC book for the win on understanding that. Might be my new favorite set of books.

    • @d2factotum
      @d2factotum Před 2 lety +3

      I was kind of wondering why he never mentioned that the different clock speeds between PAL and NTSC machines would likely cause an issue with the simple loop timer.

    • @OscarSommerbo
      @OscarSommerbo Před 2 lety

      Testing with Vice (C64SC), the loop counts I found were 625 for PAL and 780 for NTSC. I also stashed TI into a variable to eliminate PRINT messing with the count, it doesn't seem to impact the jiffie count though.

    • @csbruce
      @csbruce Před 2 lety +2

      Does the "IF TI

    • @8_Bit
      @8_Bit  Před 2 lety +3

      Was it only the FOR/NEXT loops that were substantially different on PAL? I would think the TI polling and WAIT methods would be the same, at least within a jiffy. But yes, I should have mentioned PAL. No matter how thorough I think I'm being, and how deep I go down the rabbit hole, there's always more :)

    • @OscarSommerbo
      @OscarSommerbo Před 2 lety

      @@8_Bit Again testing with Vice "C64SC" both polling and WAIT works as expected you just have to adjust for 50 jiffies in a second. I think WAIT method is the better choice when you need that level of accuracy, which on the C64 is exceedingly rare.

  • @jensdroessler3575
    @jensdroessler3575 Před 2 lety +3

    For the for next method: If the transition to the next power of 2 number is a problem, why not use a range of numbers already in a big power of 2 that won‘t need to transition again for the duration of the loop? Like starting at 1025 instead of 0.

    • @8_Bit
      @8_Bit  Před 2 lety +1

      That might do it!

  • @douggale5962
    @douggale5962 Před 2 lety

    5 second delay: 10 S=TI:EN=S+60*5:OF=0 20 IF TI

  • @redlinechaser7942
    @redlinechaser7942 Před 2 lety

    Super helpful for what I am about to do. Thanks! Great shows!

  • @JeremyNasmith
    @JeremyNasmith Před 2 lety +2

    Great vid!! I never used the Wait command back in the '80s as a kid programming on my uncle's c64 because I didn't understand what the operands even were. Logically, you'd think it'd be one operand with the delay in milliseconds or jiffies etc. But no! Now thanks to this vid, I understand it basically watches an address for a bit.
    Ok, how about this: let's suppose you want to make something happen at regular (ish) intervals, but want other code to execute in the meantime? I suggest something like:
    50 D=128:D1=5: D=int(D/4): Rem delay in Jiffies, seconds (ish)
    100 T=Peek(162)+D:T1=Peek(161)+D1
    ... other code...
    500 TF = Peek(161): If TF>T1 Then Gosub RegularRoutine
    510 if TF = T1 And Peek(162) >T then Gosub RegulaRoutine
    520 Goto 500
    Perhaps the delay in address 162 is too granular relative to the expected time to complete the ...other code.... bit so that part can be omitted simplifying the setup and checking.
    As long as there aren't any long loops (significantly longer than the delay vaules) this works kind of like an interrupt routine. In fact, instead of once per loop, there could be multiple checks occuring throughout the ...other code... section if necessary.
    Might be an interesting topic: how to simulate interrupts in basic?
    Thanks for the amazing content as always.

  • @Jimbaloidatron
    @Jimbaloidatron Před 2 lety +1

    Noticing that the TI max value went to 5184000 not 5183999, I tried printed TI$ while wrapping midnight repeatedly and you actually do get "240000" briefly! :-)

  • @0LoneTech
    @0LoneTech Před 2 lety

    The TI check wraparound is a modulo arithmetic problem. Finding the target threshold is easy; t=TI+d : if t>max t=t-max. The problem is there's time before the wraparound happens, so TI>t already. So you'd wait for TIt. It's a bunch of logic. Furthermore, it doesn't solve the issue of when t is close to max, and we may have no jiffies when TI>t. Checking for TI=t, as you might do in hardware, wouldn't do if basic might be too slow to read TI at the right jiffy (though maybe it is fast enough if you're not printing).
    The more generic form is comparing (TI-oldTI)%max to delta. Unfortunately there's no modulo operator in the C64 basic, afaik. So you'd calculate dt=(TI-oldTI), then fix it up by adding max if dt

  • @Charleshawn66
    @Charleshawn66 Před 2 lety

    Nice video! Thank you.

  • @properjob2311
    @properjob2311 Před 2 lety

    Hugo's hint was amazingly clever

  • @cmdlp4178
    @cmdlp4178 Před 2 lety +2

    Instead of TI 0 THEN 30

  • @csbruce
    @csbruce Před 2 lety +3

    0:03 I'd like to know how to achieve a sleep(-1).
    6:41 You'll be happy to hear that the SuperCPU I recycled several years ago wasn't destroyed but was kept by someone and recently sold to a professor at the University of Windsor.
    6:50 The C-128 has a method of boosting the CPU speed also…
    7:19 Did they called that the "Double Future" in "Bill & Ted's Excellent Adventure"?
    10:37 So it is the extra bit-shifting to align the mantissas for adding that's causing the difference. Your count-limit formula will need a base-2 logarithm in it!
    10:56 When X is at 15, it doesn't need to align the values as far to add the 1, but then the result is 16, which will need to be normalized by shifting the mantissa and incrementing the exponent of the result.
    11:38 The 32-bit CPUs had a barrel shifter, which can shift any number of bits in linear time. Of course, they also had direct hardware floating-point support.
    16:58 Is "5184000" a KERNAL bug? I don't think it should ever show that. It'd be like a clock going from 23:59:59 to 24:00:00 a second later and then going to 0:00:00 the second after that, giving the day an extra second.
    20:57 Just because it CAN be done, doesn't mean it SHOULD be done!
    28:50 It's just the same bits shifted left one position.
    31:12 reminds me of the DankPods credits: czcams.com/video/uuS_ZioCfDo/video.html .

    • @8_Bit
      @8_Bit  Před 2 lety +3

      That's great your old SuperCPU still exists! It seems like there might be an interesting story behind how you came to know this?
      That's true that 5184000 seems like it shouldn't exist. Oh, I just did some quick experiments, and if you repeatedly print TI$ quickly when it's about to wrap, then if you're lucky you'll see time "240000" printed once between many "235959" and "000000"! Certainly seems like a bug, but probably only adds 1/60th of a second to the day, instead of a full second.
      Seems I have to speed up the credits a LOT more to match DankPods. I usually have some reason behind how I customize the credits each episode. This time I (re)discovered a stash of my music that I wanted to use, and when I found this song we deliberately recorded to be only 30 seconds, I thought it would be an amusing contrast in a video all about WAITing to do anything but with the credits.

    • @csbruce
      @csbruce Před 2 lety

      @@8_Bit: I simply had put my name on my old Commodore equipment and the buyer either was familiar with my name or looked it up, perhaps to see if the items were stolen.

  • @SeanBZA
    @SeanBZA Před 2 lety

    Did something similar, just used string to get the time, and then looped till seconds time rolled over to 0, then waited in another string till seconds time rolled over to 2, before exiting. Got me a good 1 minute count routine, which I was using a lot, calling it for delays.
    Then did some IO, and counted minutes again. Was using this to run some automation to duplicate tapes, outer loop ran the number of total machine cycles, then the next loop ran the machine cycle, for a complete run of the machine, which was variable set at start. Then at the end it stopped, rewound the tape to the beginning ( fixed time, not worth doing anything more complex), and ejected, which also loaded the new tape. Then emulated pressing record and play, and waited for the cycle time again.
    An update for the wait loop, as I had a lot of time, was to use it to clear the screen every 30 seconds (look in string for seconds equal to 30) and randomly choose a screen location, and print the assorted timers in the system. Glitchy at 30 seconds, so that got a short roughly 1 second for next loop to not spam the screen, and again at the 0 second mark, implementing a simple screen saver for the well used mono HGC monitor I was using for output.
    Ran for a good number of years with no issue, replacing an original controller that was unreliable and temperamental on it's good days, and downright ornery when it was not. I got tired of fixing this thing, as timings were all set using really long RC delays, using 555 timers and 10000uf capacitors, which was not at all repeatable. Instead looked at the pile of old PC's, and chose a nice reasonably new 386SX16 motherboard that I had 2 spares of, put in the requisite video card, keyboard, 3.5in diskette drive, and MSDOS 6.22. Used a parallel port card as the IO, writing direct to the port address to use the bits to emulate the keys on the wired Matsushita remote control for all functions. Controllers in the case, and powered off the 12V rail, as they had on board regulators, and a bit of software, and the original controller was dismantled.
    Still got the computer, but no monitor for it, though I still have a keyboard that will work, and it likely will still boot and run.

  • @TravisTev
    @TravisTev Před 2 lety +2

    Regarding the midnight wrap-around, IBM BASIC had a similar problem when using the TIMER function for delays, and I had an old BASIC reference book that suggested a delay routine that could properly handle the wrapping problem. It looked roughly like this:
    (TIMER returns current system time in seconds as a float, mod 86400)
    seconds = (number of seconds to wait)
    t = TIMER
    if 86400 - t < seconds + .15 then t = t - 86400: while timer > 0: wend
    while TIMER < t + seconds: wend
    It seems like this could be adapted to fit the C64 case. What it seems to do (if I'm interpreting the code correctly) is determine first whether the system timer would overflow during the delay. If not, it delays in pretty much the same way as given in the video. If it will (presumably the .15 in the expression "86400 - t < seconds + .15" is just a safety net to compensate for BASIC execution overhead), then it appears to loop until the system timer has overflowed first and adjusts the value of t so that when it goes to the second while loop (the usual delay loop) it ends up waiting the correct amount of time that remains for the delay *after* the overflow (that is, the total time to wait minus the amount of time it took until the timer overflowed).

  • @madyogi6164
    @madyogi6164 Před 2 lety

    Lol, PitStopII - I loved it... hours spent with a friend on a split screen, racing... :D

  • @Jimbaloidatron
    @Jimbaloidatron Před 2 lety

    10 T=TI+59
    20 IF T>=5184001 THEN T=T-5184001
    30 IF TT THEN 30
    40 IF TI

  • @ronalddavis8228
    @ronalddavis8228 Před 2 lety +1

    My attempt at this is:
    1 X=120 (Whatever the delay is in Jiffies)
    10 TI$="235959" (Set Jiffy Count for testing)
    20 PRINT TI
    30 T=TI+X
    40 IF T

    • @adymode
      @adymode Před 2 lety

      Nice, this is similar to my attempt. I would just simply this formula for clarity: T=X-(5184000-TI)-5 to T=TI+X-(5184000+5) . I guess those 5 jiffies are to compensate for TI changing between the execution of first T calculation and re-calculation. Im not sure if just T=T-5184000 would suffice there.

  • @sutorippuwebmaster8783
    @sutorippuwebmaster8783 Před 2 lety +1

    I seem to recall that they made this simpler in BASIC 7.0 for the 128, but I'd have to dig out my old books.

    • @LordRenegrade
      @LordRenegrade Před 2 lety +1

      Yep, it's simply SLEEP . Annoyingly though it only sleeps for integer seconds (3 is the same as 3.5 for SLEEP)... :C

  • @dojcubic
    @dojcubic Před 2 lety

    my solution to wait using the TI variable and handling the wrap around:
    5 TI$ = "235959"
    10 PRINT TI
    15 S = TI : REM STORE START TIME IN S
    20 T = S + 60 : REM STOR END TIME IN T
    25 IF T >= 5184000 THEN 50 : REM OVERFL
    30 IF TI < T THEN 30
    35 GOTO 100
    50 T = T - 5184000 : REM WRAP AROUND T
    60 IF TI >= S OR TI < T THEN 60
    100 PRINT TI

  • @Darxide23
    @Darxide23 Před 2 lety

    Dave from Dave's Garage had a really great job explaining floating point math. It's the first time I ever heard the word "mantissa." I don't know how I went all this time without knowing that word. Anyway, the funny thing was that the video wasn't even about floating point math. He just covered it to explain something else. I believe it's in the second part of his two parter about "Quake III's Secret Algorithm."
    I don't know C64 Basic, but in QBasic I always used TIMER, which is just like the TI$, except TIMER counts in milliseconds. Just reference TIMER for your wait loops and you can time things down to almost the millisecond. QBasic code is never quite fast enough to catch the exact millisecond, but you can get within 3 or 4 on a typical 486 of the day.

  • @MrThomashorst
    @MrThomashorst Před 2 lety +1

    Damn ... as soon as i saw the 4 bit pattern it hits me like the guy on twitter ... now i'm happy that after 34 years i'm still into this crap 😀

  • @merykjenkins3274
    @merykjenkins3274 Před 2 lety +6

    Would a nested loop with outer loop being the number of required seconds and inner being the one second delay. It wouldn't be doing math with big numbers, it might keep it more stable? Thanks for the video Robin, the "directors cut" is making me think more!

    • @That_Handle
      @That_Handle Před 2 lety

      Hm... Yeah - esp. when adding a ~calibration loop when compensating for ~processing speed across different machines?

  • @coding_and_things
    @coding_and_things Před 2 lety +2

    10 TI$="000000"
    20 FOR I=0 TO 50:WAIT 53265,128:NEXT
    30 PRINT TI/60
    Here I'm counting the frames processed in one second. Alter the value in the FOR statement 50 for PAL, 60 for NSTC. 🙂

  • @Koutsie
    @Koutsie Před 2 lety

    All of these future Robins could make a whole cinematic universe, good video tho!

  • @mikegarland4500
    @mikegarland4500 Před rokem

    Thanks for this. Explains a lot about something that "seems simple," but isn't.

    • @mikegarland4500
      @mikegarland4500 Před 11 měsíci

      I think he was trying to get a more definitive method of specifying a certain time, rather than a loop that could have different time lengths depending on CPU load, etc.
      But I agree, for general purposes the FOR:NEXT loops are definitely the easier method. @@Joel-qz6sd

  • @StephenGutknecht
    @StephenGutknecht Před 2 lety

    I"m curious if moving joystick or touching keyboard throws off the loop, as the system would get interrupted? incoming modem data may also do that too (I used to write C64 BBS systems).

  • @ukcroupier
    @ukcroupier Před 2 lety +3

    New lines take longer to process than semicolons, so to get a more accurate reading you should use
    10 TI$="000000":FOR I=1 TO 1000:NEXT:?TI
    This will show the loop to take 63 jiffies instead of 64 when using seperate lines.

  • @tenminutetokyo2643
    @tenminutetokyo2643 Před 2 lety

    Those slight divide errors are known as floating point drift and are endemic on machines lacking math coprocessors. This is why computer makers later added math chips.

  • @jmcdowall
    @jmcdowall Před 2 lety +3

    I remember using FOR NEXT exclusively for delays, then my dad blowing my mind by showing that stuff could go in-between the FOR and NEXT...

    • @8BitNaptime
      @8BitNaptime Před 2 lety +1

      Even more fun, you can modify the value of the index in the loop to cause it to exit or never exit, like a hacked do... while kinda thing.

  • @JustWasted3HoursHere
    @JustWasted3HoursHere Před 2 lety

    Would the WAIT command method give reliable results on a PAL C64 running at .985mhz and with a 50hz refresh rate?

  • @GeoffSeeley
    @GeoffSeeley Před 2 lety

    @11:50 that should be interesting! In my experience, no two floating point libraries ever work exactly the same. Had loads of fun with a financial/HR system that needed to map 12 period fiscal into a 13 period fiscal during transition to a new system.

    • @douggale5962
      @douggale5962 Před 2 lety

      Don't blame floating point for not being able to exactly represent irrational numbers. It's not even possible.

  • @Ensign_Cthulhu
    @Ensign_Cthulhu Před rokem

    And finally I understand the WAIT command.
    The instruction manual I got with my C64 did an absolutely terrible job of explaining this. Commodore did a terrible disservice to their machine by not shipping it with the far more comprehensive user's guide; it might have kept more of its younger users into programming and away from games (that they didn't write themselves).

  • @bozimmerman
    @bozimmerman Před 2 lety +4

    Kinda surprised one of the TOD clocks wasn't used. That's how I handle timeouts in ML. It also has the advantage of not being disrupted by I/O.

    • @8_Bit
      @8_Bit  Před 2 lety +1

      Seems like it'd be pretty ugly to use the TOD from BASIC, but I've never tried. The numbers are in BCD, aren't they? Polling them would be pretty bad, and since seconds are separate from the 1/10th of a second, we'd have to read two registers to do accurate timing. Seems like an interesting solution for ML and GEOS programming, but it really doesn't seem appropriate to me for BASIC unless I'm missing something.

    • @jjeeeekk
      @jjeeeekk Před 2 lety

      ​@@8_Bit I posted an example in @Shawn Lucas comment "How about reading the TOD registers on the 6526 IC?"
      This variant is very useful to benchmark routines which inherently run with disabled interrupts ...

    • @SIDCIAVIC
      @SIDCIAVIC Před 2 lety

      @@8_Bit It's easy enough to set all bytes to zero and use it for elapsed time.

  • @QWDreaming
    @QWDreaming Před 2 lety

    Essentially similar to the final "Another WAIT approach", if you set TI$="000047", then run WAIT 162,64, it should work for one second because it also sets the timer's low byte to 4. POKEing 162 is probably more elegant!

  • @gregmark1688
    @gregmark1688 Před 2 lety +1

    There's probably no way to fully fix your wrap-around problem (you're always going to have a single shortened delay time just before midnight), but you can easily avoid the infinite loop by re-arranging your test. This is how I usually do this sort of thing:
    20 T=TI
    30 IF ABS(TI-T) < 60 then 30
    When TI wraps to 0, ABS(TI-T) will become a large positive number, and the loop will terminate.

  • @stephaneedwardson1370
    @stephaneedwardson1370 Před 2 lety +1

    Wouldn't POKE162,4:WAIT162,64 give a 1 second delay every time, without the need to reset TI$ or to use multiple WAIT in sequence?

  • @herdware
    @herdware Před 2 lety +2

    That quirky WAIT behavior has bit me once in the past.

  • @fluffycritter
    @fluffycritter Před 2 lety

    I was going to ask the same question as your patron and was ready to post it right before you got to that future-future update. I'm surprised it's so nonlinear. I wonder if the time factor would be more predictable if you used integer variables instead of floatingpoint (even though they're slower overall per that other video you did a while ago).

    • @jjeeeekk
      @jjeeeekk Před 2 lety +1

      FOR-NEXT does not allow integer variables! Beside of that ever operation is done in floating point, even integer variables are converted to FP and back to store it. ;)

  • @whizadree
    @whizadree Před 2 lety

    Could you take a number (a) being your time to wait convert it to binary . Now taking that result and set as either 1 or 0 ( b c d e f g h i) as you did set up the truth table 128 ' 64 ' 32 '16 ' 8 ' 4 ' 2 '1 .. then run a if statement to test the logic of b thru I. Running a wait 162 , 128 thru to 1 running the wait if true and not running if false ??? Possible?

  • @stefanocrespi5424
    @stefanocrespi5424 Před 2 lety

    I'd love to see if these approaches works the same way on basic 3.5 and basic 7.0, 264 and 128 machines respectively.

  • @mikechappell4156
    @mikechappell4156 Před 2 lety +1

    5 TI$="235959"
    10 PRINT TI
    20 Q=TI:T=TI+61
    25 IF V=0 THEN IF TI

    • @adymode
      @adymode Před 2 lety

      Ingenious mechanism. Only drawback is the overall loop would cycle less frequently than the simple 'IF TI

    • @mikechappell4156
      @mikechappell4156 Před 2 lety +1

      @@adymode Thanks. It could be optimized a bit by only adding the day carry when needed. I haven't tested it yet, but I assume an extra test and jump might be quicker than the floating point addition. You can do quite a bit of optimizing when you know the ins and outs of C64 BASIC, but optimized code usually isn't very pretty.

  • @TrollingAround
    @TrollingAround Před 2 lety +2

    Without changing the clock:
    10 T=(PEEK(162)+60) and 255
    20 IF PEEK(162)T THEN 20
    (although if there are TSRs running in the background this _could_ fail - but testing under VICE it works reliably in normal circumstances with CPU running anywhere down to 10% of normal).

    • @TrollingAround
      @TrollingAround Před 2 lety +1

      Although:
      clc
      lda 162
      adc #60
      cmp 162
      bne 252
      rts
      in hex: 18 a5 a2 69 3c c5 a2 d0 fc 60
      in decimal: 24 165 162 105 60 197 162 208 252 96
      compiles down to 10 bytes (arguably you could omit the 'clc' without much error, perhaps it would pause for an extra 1/60 of a second). The code is relocatable, so poke it somewhere available (49152 to 49161) and sys it (sys 49152) when you need a (pretty darn accurate) one second delay.

  • @fllthdcrb
    @fllthdcrb Před 2 lety

    It makes sense that additions for the default FP variables in BASIC wouldn't have consistent time, considering the 6510 doesn't have hardware FP. (Heck, it doesn't even have integer multiply and divide!) Maybe it would be better to use integer variables, which have names suffixed with "%", if maybe still not perfect (because they're 16-bit on an 8-bit machine, possibly introducing a few cycles difference whenever there's a carry). Just be aware that they're limited to a 16-bit signed range. ...Then again, I would expect the integer math to be much faster and thus require counting to higher numbers for the same delays, so maybe it's not too scalable.

  • @what-uc
    @what-uc Před 2 lety +1

    What does WAIT X,0 do? And would this work to wait the specified number of jiffies?
    TI$+"000000"
    WT=90
    WAIT 162,WT AND 128
    WAIT 162,WT AND 64
    WAIT 162,WT AND 32
    WAIT 162,WT AND 16
    WAIT 162,WT AND 8
    WAIT 162,WT AND 4
    WAIT 162,WT AND 2
    WAIT 162,WT AND 1

    • @jjeeeekk
      @jjeeeekk Před 2 lety +1

      No, this won't work. The first WAIT waits for ever, because the bit with value 128 is not set in WT, the AND gives zero, a "WAIT location,0" never matches because (PEEK(location) AND 0) != 0 won't succeed.
      This fix this, you must wait for an unset bit, which could be achieved with
      WAIT 162, 128, NOT(WT) AND 128
      WAIT 162, 64, NOT(WT) AND 64
      WAIT 162, 32, NOT(WT) AND 32
      WAIT 162, 16, NOT(WT) AND 16
      WAIT 162, 8, NOT(WT) AND 8
      WAIT 162, 4, NOT(WT) AND 4
      WAIT 162, 2, NOT(WT) AND 2
      WAIT 162, 1, NOT(WT) AND 1
      The 3rd parameter of WAIT is the flip mask (xor operation on the location content before and-ing it), which may invert a bit before the "and" mask is applied. Without the flip mask, is is assumed to be zero, which let the value untouched. Just in case we have an unset bit, NOT turns all unset bits into 1, the AND focuses on the bit needed, which finally acts as flip mask. ;)

  • @frankb763
    @frankb763 Před 2 lety

    Hello, I have written a basic extension that from 49152 is in memory. After loading the programm, however, the pointer on basic end is behind $ C000, so the basic code is not running. Is there a trick?
    10 Load "Basic extension", 8.1
    20 My Basic Program Code ....
    30 ....
    40 ....
    50 SYS49152, Bla Bla Bla
    and so forth...
    I basically only want one basic code that brings a machine program to his right address and then continues to normal in the basic code.
    I hope you can understand what I mean
    Thank you
    Frank from Germany

    • @frankb763
      @frankb763 Před 2 lety

      Everything OK. I found it. Here my result:
      10 if peek(49157)=32thengoto30
      20 load"window",8,1
      30 poke55,0:poke56,160
      40 rem*******************************
      50 dim a$(40)
      60 forx=0to39:readb$:a$(x)=b$:next
      .
      .
      .
      .

  • @vcv6560
    @vcv6560 Před 2 lety

    @8 Bit Show and Tell, what's the story about the Pitstop II box in the video, I sat through this a second time and still don't get it. Thanks.

    • @8_Bit
      @8_Bit  Před 2 lety

      Hi, sorry to say that there's no huge significance to the games I put in videos. If there's an empty area on the table in the camera's view, then usually I'll pick a game from my collection and put it in that spot. I looked into it a bit and it seems I've "featured" a game in this way about 90 times out of the ~130 episodes I've made. I usually try to choose a different game each time but sometimes I repeat by accident or on purpose. I think I originally drew a bit of inspiration from Strong Bad's emails, as there was usually a different disk visible each cartoon in his floppy disk holder. Maybe what you're wondering is how I choose the particular game from my collection? Usually I know the subject of the video so I search my shelves looking for something that has some kind of collection. In this case the episode idea was about WAITing, so a Pitstop seemed appropriate.

    • @vcv6560
      @vcv6560 Před 2 lety

      @@8_Bit WAITing == Pitstop, yes funny

  • @Simcore999
    @Simcore999 Před rokem

    👍

  • @G7VFY
    @G7VFY Před 2 lety +1

    I wish I knew that 40 years ago

  • @JesusisJesus
    @JesusisJesus Před 2 lety

    Does the program have some load on the time counting?

    • @JesusisJesus
      @JesusisJesus Před 2 lety

      Aaaand he answered my question at around 15 minutes.

  • @the_socially_distant
    @the_socially_distant Před 2 lety

    Unrelated to this video but a general Commodore question. In CBM Basic, you know those special formatting characters that appear between quotes (ie the Reverse heart for CLR HOME, reverse S for HOME, and other reverse symbols for the different colours, etc). One thing that has puzzled me for decades about my old VIC-20 I had as a kid, between open quotes, the "Run Stop" key shows a reverse C. I've never been able to figure out what that does though (if anything)? I figure if anybody is going to know, it's going to be you. Any insight?

    • @8_Bit
      @8_Bit  Před 2 lety +1

      I believe it has to do with the STOP key's relation to the cancel/break functions of other computers. In operating systems like Unix, CP/M, and MS-DOS you hit Control-C to cancel or stop a command, so it makes sense that STOP on the Commodore machines prints a "C" symbol. It doesn't do anything, as far as I know, if you print it to the Commodore's screen, but if you're connected to another machine by serial / modem link, then sending that character may very well cause the receiving computer to respond.

    • @the_socially_distant
      @the_socially_distant Před 2 lety

      @@8_Bit Very interesting! I never thought about that, that seems very logical. I've learned a lot watching your videos!

    • @8_Bit
      @8_Bit  Před 2 lety +1

      @@the_socially_distant Thanks. I've done some research for an episode just about RUN/STOP so that's when I looked into that particular aspect of it. Hopefully I'll get around to making the video sometime soonish!

    • @the_socially_distant
      @the_socially_distant Před 2 lety

      @@8_Bit I will look forward to it!

  • @falksweden
    @falksweden Před 2 lety +1

    All this video is missing is a DeLorean :)

  • @vhm14u2c
    @vhm14u2c Před 2 lety

    Just want add another possible wrench to this. I learned of this from a c64 repair vid on YT, where a diags cart tested many things good, but c64 would not run. Someone commented to look at the system clock in the bottom corner on diags, it was frozen. When they seen the part of the schematic, was a bad cap I believe, it uses the 60hz (US)from the input power to make the time clock run on the c64. (That was not expected). So in essence, in UK, would be 50 hz, which would be different numbers. Might be able to see that In emulation. Not sure though.

    • @8_Bit
      @8_Bit  Před 2 lety

      That only affects the Time Of Day (TOD) clock which (somewhat strangely) both TI and TI$ don't use at all. So PAL/NTSC has no effect on either the TI or WAIT methods. PAL/NTSC does have an impact on the FOR/NEXT method, but not due to the TOD, but rather just the differences in clock speeds and different number of cycles eaten by VIC-II DMA on NTSC and PAL models.

  • @TheSudsy
    @TheSudsy Před 2 lety

    so WAIT x,y is sort of If (PEEK x) = y. IF statements are usually slower than other commands. WAIT is useful maybe for none branching code?

    • @jjeeeekk
      @jjeeeekk Před 2 lety +1

      No, its equivalent with 10 IF (PEEK(x) AND Y) = 0 THEN 10
      Its a bitwise check of mask Y, not a comparison by value.

  • @skilletpan5674
    @skilletpan5674 Před 2 lety

    20 T=TI+61: IF T>5183999 THEN IF T>TI THEN T=T-5184000
    (I did the above line just before you pointed out the overflow issue. Then I updated it. Will the double IF work like that in C64 basic?)
    TI will automatically wrap so why reset T? Just remove the bad value. It would actually be better to loop it and keep removing 5184000 just in case you have a really bad value but I forget if C64 supports modular arithmetic. If you just need semi bullet proof code then my example should be fine.
    Also there is a delay in interpreters. You should be joining 10,20 and 30 together. putting the TI="00000000" on the same line as your for loop and then printing it after next will shorten the interpreter delay quite a bit and get a more accurate value. But then you get the argument about the added delay from the C64 basic interpreter anyway? in that case put the TI= on the same line as the for and print the result on the next line.
    I'm not a C64 basic guy. I was coding a little on APPLE ][s but similar issue are on both.

  • @dr.ignacioglez.9677
    @dr.ignacioglez.9677 Před 2 lety

    I REALLY LOVE C64 👍🥂🎩

  • @MrMaxeemum
    @MrMaxeemum Před 2 lety +1

    Future Robin really had his work cut out for him on this one.🤣

  • @sven1421
    @sven1421 Před 2 lety

    This video makes me feel like Doc Emmett Brown. ;)

  • @berndeckenfels
    @berndeckenfels Před 2 lety

    Wow, that TI$ was new to me

  • @alerey4363
    @alerey4363 Před 2 lety +1

    maybe the problem is that your exponential formula takes more time to compute and the TI variable reflects that, which is an error introduced by the formula itself; also a more simple appproach without all these drifts is:
    0 S = 1
    10 TI$="000000"
    20 IF TI>60*S THEN ? TI : END
    30 GOTO 20
    S being the time to wait in seconds; you will err on the plus size but hopefully on the 1/100th of a second, consistently above the target wait

  • @DropDeadFrederick
    @DropDeadFrederick Před rokem +1

    What about using the clock timer in the CIAs?

  • @AlexEvans1
    @AlexEvans1 Před 2 lety

    If you start your for loop with a large value like: x=133000:y=x+v*t:for i=x to y:next i then you will remain linear for a large range of seconds. for using the system clock, to make up for the rollback to 0, you can use a pair of loops. You etst if it will overflow, if not you goto the second loop. if it will you start with a loop that waits for the overflow.

  • @sebastian19745
    @sebastian19745 Před 2 lety

    Is there a reason for you not using spaces?
    I know of various BASIC dialects that had more free RAM if not using spaces and others that do not allowed missing space from syntax (FOR I=1TO10 is different than FOR I=1 TO 10).
    On machines with low RAM (4K) I saw that some BASIC dialects allowed omission of spaces.

    • @8_Bit
      @8_Bit  Před 2 lety +1

      Commodore BASIC doesn't require spaces and the manuals actually encouraged programs to be "crunched" as they called it as each space takes an extra byte to store, and a little bit more CPU time to parse. I do try to use spaces more in my videos for better readability, but don't always remember. I think I used spaces in most examples in this video?

  • @williamsquires3070
    @williamsquires3070 Před 2 lety +1

    I’d just wait ‘X’*60 jiffy’s in an infinite loop, then exit when ‘TI=X*60’ (assuming 1 jiffy=1/60th sec, and ‘X’ is the desired delay in seconds.) 😌

    • @RiggieHeartland
      @RiggieHeartland Před 2 lety

      Don't need to be a loop. Just check in one line and go to the same line as long as TI hasn't reached the value

  • @nunyobiznez875
    @nunyobiznez875 Před 2 lety

    19:30 I believe the easiest solution there would be to reset 'ti' if the overflow limit is reached, then repeat the 't' variable assignment. For example, changing line 20 to read:
    20 t=ti+61: if t > 5183999 then ti$ = "000000": goto 20
    Technically greater accuracy could still be achieved, so I don't know if I'd call it a perfect solution if someone is planning to use their original C64 hardware for 24/7 monitoring of a nuclear reactor 😄. But otherwise, it should be good enough for most practical purposes.

    • @adymode
      @adymode Před 2 lety

      Adjusting the ti counter in the case of an overflow is an interesting direction to take, but in the example you have there when line 20 happens with ti in the last second of 48 hours, the line sticks with ti getting set to 0 on every loop and t just keeps getting 60 jiffies added until some sort of math overflow or exception occurs. But the basic idea seems worth exploring.

    • @nunyobiznez875
      @nunyobiznez875 Před 2 lety

      ​@@adymode I believe you misread or misunderstood something. The 'if' conditional does not execute any part of the statement after the 'if' unless the condition is true, which in this case, is only true when the value of 't' is greater than 5183999. If the 'if' conditional is false, that also prevents the final goto statement at the end from being reached, as well. So if the value of 't' is over the limit, the goto will only rerun the statement again one time, to recalculate the value of 't' again. After which, the value of 't' will be set to 0 + 61, which will cause the 'if' statement to be false, and the rest of the statement will not be run again. Execution should continue on normally, to the next line. I'm not beyond mistakes, but I always test my code before I post it, usually even for simple code, just to be sure. But you are welcome to test the code with the rest of his original program. Everything else is the same as the original program, except for line 20, which I posted. If you still think I have an error here, then I'd like to hear where and why you believe it's an error.

    • @adymode
      @adymode Před 2 lety +1

      @@nunyobiznez875 Oh yes of course ! I see now, thanks for explaining. That is a great tweak.

  • @mrkattm
    @mrkattm Před 2 lety

    I have very limited experience with the c64 but couldn't you just setup an interrupt to vector to some routine every second? It is still basic because you would be doing it with peeks and pokes

    • @8_Bit
      @8_Bit  Před 2 lety

      It's possible, but I'm just looking at "pure" BASIC solutions in this video that don't use any machine language.

  • @G7VFY
    @G7VFY Před 2 lety

    With PAL machines, are jiffy's 1/50th of a second?

    • @branchonequal
      @branchonequal Před 2 lety

      Yes!

    • @8_Bit
      @8_Bit  Před 2 lety +2

      On the Commodore 64, jiffies are 1/60th of a second whether PAL or NTSC. They're driven by a timer on the CIA, completely unrelated to the video refresh. You can verify this with a short program such as:
      10 ti$="000000"
      20 ?ti$;ti:goto20
      You'll notice that the jiffy count (TI) on the right side will exceed 50 (it'll probably get up to 57, 58, or 59) while TI$ is still showing 000000. TI$ does not return 000001 (one second) until TI reaches 60 on both NTSC and PAL.

    • @jjeeeekk
      @jjeeeekk Před 2 lety

      @@branchonequal No, as Robin already explained it.

    • @branchonequal
      @branchonequal Před 2 lety

      @@8_Bit Hi Robin, interesting! I haven't checked it myself but at least the C64 Wiki is wrong then. It clearly states
      "In countries using the NTSC standard this is 59.94 Hz (16.8 ms) while in countries using the PAL standard this is 50.0 Hz (20.0 ms)."
      Thanks for the explanation!

    • @8_Bit
      @8_Bit  Před 2 lety +1

      ​@@branchonequal Aha thanks, I hadn't noticed that entry on C64 Wiki; maybe that's the main source of this misinformation. I see that none of the sources on that page back up the C64-specific assertions made. But there's a big contradiction and proof of 60-jiffies-per-second even on that page. It correctly states that "After the clock is incremented, the number $4F1A01 (or 5184001 jiffies, which is 24 hours + 1 jiffy) is therefore subtracted from the 24-bit count." If 5184001 is 24 hours + 1 jiffy, then we can easily determine that there are 60 jiffies per second, and not 50. 24 hours * 60 minutes * 60 seconds * 50 jiffies + 1 would only be 4320001. 24 * 60 * 60 * 60 jiffies + 1 equals the stated 5184001.

  • @jan-erikkarlsson7875
    @jan-erikkarlsson7875 Před 2 lety

    Hi, Robin! I wonder why you have shown cbm calculators but not cbm's first computer the KIM-1? And how it works and it's relation to early PETs (Basic etc.), and do show some programming on the C16/Plus4, C64 is yesterday News in the retroworld, time to move on 😜

    • @8_Bit
      @8_Bit  Před 2 lety

      If anyone wants to give me a KIM-1 I'll gladly show it! Have you got one for me? :) But I do happen to have a Plus/4 video coming very soon.

    • @jan-erikkarlsson7875
      @jan-erikkarlsson7875 Před 2 lety

      they are available as they were from MOS (as a kit computer) for roughly 10$ by obscelence guaranteed it's called KIM-Uno

  • @awilliams1701
    @awilliams1701 Před 2 lety +1

    lol once you explained what wait was doing I'm like.......you could wait for each bit, but that would suck..........and then you actually did it. LMAO

  • @slucas601
    @slucas601 Před 2 lety

    How about reading the TOD registers on the 6526 IC?

    • @jjeeeekk
      @jjeeeekk Před 2 lety +1

      Could be done in two ways. Init the TOD and poll the value (could be done in a consistent way because of register latching) or with the TOD alarm.
      The time range would be limited to 1/10 to 1 day, the granularity is 1/10 sec.
      Only the initialization of the TOD depends on the current frequency (50 or 60 Hz), which could be derived from KERNAL settings.

    • @slucas601
      @slucas601 Před 2 lety

      @@jjeeeekk example or tutorial?

    • @jjeeeekk
      @jjeeeekk Před 2 lety

      ​@@slucas601 I'm using the TOD for time measurements of routines which disables the interrupts ... Here a version to just elapse time, e.g. 10.5 seconds (the end value of FOR T= is the waiting time given in BCD notation (1000 means 00:10:00,0 in HH:MM:SS,T format). For comparison the TI time value is also printed. The greater the delay time the less the overhead and difference between them. This is the PAL version, the NTSC version has to use GOSUB8 in line 10.
      6 dimt,d,x:deffnt(x)=int(x/16)*10+(xand15):d=56576:goto10
      7 t=fnt(peek(d+11))*1e4+fnt(peek(d+10))*100+fnt(peek(d+9))+fnt(peek(d+8))/10:return
      8 poked+14,127andpeek(d+14):poked+15,127andpeek(d+15):poked+11,0:poked+10,0:poked +9,0:poked+8,0:return
      9 poked+14,128orpeek(d+14):poked+15,127andpeek(d+15):poked+11,0:poked+10,0:poked +9,0:poked+8,0:return
      10 gosub9:t0=ti:printchr$(147)
      11 fort=0to10.5step0:gosub7:printchr$(19)t;chr$(157)" ":next
      12 print "time elapsed:"t,(ti-t0)/60
      Maybe you have to split the line into separate ones because they are to long, or use the abbreviated commands, like
      7t=fnt(pE(d+11))*1e4+fnt(pE(d+10))*100+fnt(pE(d+9))+fnt(pE(d+8))/10:reT
      8pOd+14,127aNpE(d+14):pOd+15,127aNpE(d+15):pOd+11,0:pOd+10,0:pOd+9,0:pOd+8,0:reT
      9pOd+14,128orpE(d+14):pOd+15,127aNpE(d+15):pOd+11,0:pOd+10,0:pOd+9,0:pOd+8,0:reT

    • @8_Bit
      @8_Bit  Před 2 lety +1

      ​@@jjeeeekk Nice work! It's slightly less hideous than I imagined, but still pretty bad. Excellent!! :)
      Since you put both the PAL and NTSC init in there anyway, I just modified line 10 to automatically call the correct one, assuming the NTSC/PAL flag is set correctly. And yeah, lines 8 and 9 needed every last character squeezed out of them; they're both 80 characters! Nice job.
      6dimt,d,x:deffnt(x)=int(x/16)*10+(xand15):d=56576:goto10
      7t=fnt(pE(d+11))*1e4+fnt(pE(d+10))*100+fnt(pE(d+9))+fnt(pE(d+8))/10:reT
      8pOd+14,127aNpE(d+14):pOd+15,127aNpE(d+15):pOd+11,0:pOd+10,0:pOd+9,0:pOd+8,0:reT
      9pOd+14,128orpE(d+14):pOd+15,127aNpE(d+15):pOd+11,0:pOd+10,0:pOd+9,0:pOd+8,0:reT
      10on(peek(678)+1)gosub8,9:t0=ti:printchr$(147)
      11fort=0to10.5step0:gosub7:printchr$(19)t;chr$(157)" ":next
      12print "time elapsed:"t,(ti-t0)/60

    • @jjeeeekk
      @jjeeeekk Před 2 lety

      @@8_Bit Your initialization switch is pretty nice and handy too. :)

  • @mrmimeisfunny
    @mrmimeisfunny Před 2 lety

    Here's my solution to the TI Epoch bug
    10 TI$="235959"
    20 PRINT TI
    30 T=TI+61
    40 IF TI=0 AND T>5184000 THEN T=T-5184000
    50 IF TI

  • @SerErris
    @SerErris Před 2 lety

    I love the 24 hour endless loop. But realistically .. the C64 would never hold out 24 hours of continous runtime. Either the Power Supply would burn through or the internal chips would burn up because of heat. Most likely it will simply crash :-)

    • @0LoneTech
      @0LoneTech Před 2 lety

      Why would you assume that? It's not like some Windows machine running hundreds of weird processes, some of which may decide to reboot your machine at any time. The amount of power, and thus heat, doesn't change much over time. They've been used for industrial control applications.

  • @MattKasdorf
    @MattKasdorf Před 2 lety +1

    Now a (1s) delay in assembly, that works at C64 (NTSC/PAL), 1MHz and 48MHz speeds.

    • @Breakfast_of_Champions
      @Breakfast_of_Champions Před 2 lety +1

      The CIA timers, simple. They trigger an interrupt so it's a background activity. The whole idea of doing an exact wait in BASIC is mission impossible from the start😉

    • @csbruce
      @csbruce Před 2 lety +1

      You could use the TI value (memory locations 160-162) in the same way as with the TI

  • @awilliams1701
    @awilliams1701 Před 2 lety

    ultimate 1541 2+ at least does not have a CPU boost function. As far as I know only the U64 has that in the ultimate product line.

  • @8BitNaptime
    @8BitNaptime Před 2 lety

    I think using a DEF FN is a good solution for pausing for a specific time.
    10 DEF FN D(X)=X*920
    100 PRINT TI/60
    110 FOR I = 0 TO FN D(1)
    120 NEXT
    130 PRINT TI/60
    Seems to work, just pass the time in seconds in the FN T().
    I haven't tested this exhaustively, it's like 2AM ....

    • @8BitNaptime
      @8BitNaptime Před 2 lety

      I also observed a non-linear behavior when the delay is greater than 5 seconds.
      Next I tried a lookup table but that only works with whole numbers.
      10 dim d%(10):gosub 1000
      20 printchr$(147)
      100 for l =1 to 9
      110 a=ti/60
      120 for i = 0 to d%(l):next
      130 print l;d%(l);ti/60-a
      140 next
      998 list
      999 stop
      1000 d%(1)=960:d%(2)=1920:d%(3)=2880
      1010 d%(4)=3840:d%(5)=4800:d%(6)=5600
      1020 d%(7)=6500:d%(8)=7400:d%(9)=8300
      1900 return
      And these tweaked numbers give interesting results
      1 960 1
      2 1920 1.98333359
      3 2880 3
      4 3840 4.03333283
      5 4800 5.08333302
      6 5600 6
      7 6500 7.01666642
      8 7400 8.03333283
      9 8300 9

    • @8BitNaptime
      @8BitNaptime Před 2 lety

      Maybe not non-linear, more like an inflection point at around 5 seconds.

    • @8BitNaptime
      @8BitNaptime Před 2 lety

      I couldn't let it go. I changed the time calculation's place since calculating it after the print is wrong.
      1 980 1
      2 1970 2
      3 2930 3.0166626
      4 3850 4
      5 4780 5
      6 5670 6
      7 6570 7
      8 7470 8
      9 8370 8.96667481
      10 dim d%(10):gosub 1000
      20 printchr$(147)
      100 for l =1 to 9
      110 :a=ti/60
      120 :for i = 0 to d%(l):next:b=ti/60
      130 ::print l;d%(l);b-a
      140 next
      998 list
      999 stop
      1000 d%(1)=980::d%(2)=1970:d%(3)=2930
      1010 d%(4)=3850:d%(5)=4780:d%(6)=5670
      1020 d%(7)=6570:d%(8)=7470:d%(9)=8370
      1900 return
      This seems to work nicely. I guess.

  • @rotordave81
    @rotordave81 Před 2 lety

    Future Robin should get his own channel if he's going to interrupt so much.

  • @drsquash2003
    @drsquash2003 Před 2 lety

    Couldn't you just do an if then then else loop looking at the value for TI?

    • @8_Bit
      @8_Bit  Před 2 lety +1

      I think that's what I show as the second technique?

    • @drsquash2003
      @drsquash2003 Před 2 lety

      @@8_Bit omg you noticed me lol. Yeah i realized that shortly after I posted it. And yet it still wasn't a perfect solution

  • @anotheruser9876
    @anotheruser9876 Před 2 lety +1

    10 T=3:TI$="000000"
    20 IF TI/60

  • @jjeeeekk
    @jjeeeekk Před 2 lety

    3:40 Why exponential? It is probably meant polynomial, isn't it? As far as I understand maths, X^2 is polynimial and 2^X is exponential. But I have to admit, I'm not a native apeaker, so maybe in English this term might be used for both...

    • @8_Bit
      @8_Bit  Před 2 lety +1

      Interesting! I used the word exponential just because I was using exponents rather than linear multiplication but it seems polynomial is the correct word. I googled around and maybe the word "sublinear" is also appropriate?

    • @jjeeeekk
      @jjeeeekk Před 2 lety

      Yes, non-linear might be also a reasonable term. Sublinear sounds like "constant" to me. If polynomial increase is regarded as bad, an exponential increase is really really bad. A differnce which is significant in comparing P, NP and NP-complete problems the holy grail of problems in the field of informatics. ;)

  • @EgonOlsen71
    @EgonOlsen71 Před 2 lety +4

    Busy wait FOR-loops are evil. It's not just about them running faster on faster CPUs, but in compiled code as well. In fact, my BASIC cross compiler detects that these are empty loops and replaces them by setting the variable's value directly to the final value by default...and there goes your wait...:-)

  • @bierundkippen720
    @bierundkippen720 Před 2 lety

    I use my iPhone timer for this.

  • @RonHelton
    @RonHelton Před 2 lety

    So there is more than one way to "skin a cat". ; )

  • @TheUtuber999
    @TheUtuber999 Před 9 měsíci

    I was able to get a perfect time delay by simply modifying the string on line 20 below...
    _One Second Delay:_
    10 ti$="000000"
    20 ifti$"000001"then20
    30 printti/60
    _Five Second Delay:_
    10 ti$="000000"
    20 ifti$"000005"then20
    30 printti/60
    _Ten Second Delay:_
    10 ti$="000000"
    20 ifti$"000010"then20
    30 printti/60
    And so on...

  • @weedmanwestvancouverbc9266

    Goddammit time traveling programmers, always covering up their tracks.

  • @ronpetrick
    @ronpetrick Před 2 lety

    YOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOÒOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO

  • @sjdpfisvrj
    @sjdpfisvrj Před 2 lety

    Goodness gracious. So many responses here, and nobody mentions the modulus operators, which is how you deal with overflowing integers. I'm sorry to say, but just about everybody here would not get past a basic programming interview at a company.

    • @MurderMostFowl
      @MurderMostFowl Před 2 lety

      The c64 has no modulus operator. ( though it can obviously be implemented easily enough in assembly or in basic )

  • @nicolaluciani4496
    @nicolaluciani4496 Před rokem

    Per favore ingranndusci di piu l immagine a sinistra

  • @karlfoley
    @karlfoley Před 2 lety +1

    10 TI$="000000"
    20 IF TI$

    • @8_Bit
      @8_Bit  Před 2 lety +6

      Close, it should be 20 IF TI

    • @jjeeeekk
      @jjeeeekk Před 2 lety +1

      @@8_Bit It will work with 20 IF TI$

    • @adymode
      @adymode Před 2 lety +1

      @@jjeeeekk I thought TI$

    • @jjeeeekk
      @jjeeeekk Před 2 lety +1

      It's a little inconvenient to get the time limit value into the proper format for the comparison. You could write it as
      T=60:T$=STR$(T):T$=RIGHT$("00000"+RIGHT$(T$,LEN(T$)-1),6)

    • @adymode
      @adymode Před 2 lety

      @@jjeeeekk Building on your code I would guess, T=60 : T$="00000"+STR$(INT( T/60 )) : T$=RIGHT$(T$,6)

  • @pikadroo
    @pikadroo Před 2 lety +1

    Meh, i don’t care what patrons want.

  • @eric_d
    @eric_d Před 2 lety

    20:48 You could add "15 IF TI>5183939 THEN 15". I know you're shooting for as close to a 1 second delay as possible, and having no delay isn't a valid solution. This way you'll get a delay, but it could be up to 2 seconds, which may be a better solution.

  • @adymode
    @adymode Před 2 lety

    I renamed T as half my brain confuses it with TI but it is good to bring along both halves.
    10 PRINT TI
    20 W=TI+60

    25 REM "WRAP W BUT LEAVE ENOUGH TIME TO CATCH TI>W @50"
    30 IF W>=5183995 THEN W=W-5183995

    35 REM "WAIT FOR TI TO WRAP IF W WRAPPED"
    40 IF TI>=5183935 AND TI>W THEN 40

    45 REM "SIMPLE NOW WRAPPABLE MOMENTS HAVE PASSED"
    50 IF W>TI THEN 50
    60 PRINT TI

    • @adymode
      @adymode Před 2 lety

      In the last example which seems the optimal method, seems we should be able to fix throwing time off, by just storing TI before start and setting TI$ to correct value after the wait.