Jump to content

TheBF

+AtariAge Subscriber
  • Posts

    4,465
  • Joined

  • Last visited

Posts posted by TheBF

  1. 12 hours ago, FarmerPotato said:

    In disassembly of some TI code , I found this:  
     

    BL @SUBR

    CLR R7

    JEQ L2

    ...

     

    I was confused, but I looked up CLR and saw it does not change the status register. 
     

    Apparently R7 is used by SUBR, but this code wants R7 to be 0  before L2. 
     

    Ya that was an insight that simplified my coding of Forth conditionals.  ( = < > 0= etc.) 

    Since CLR and SETO don't play with status you can compare a register, then clear it or set it to -1 as a default result.

    Then you can change the register based on the previous comparison instruction. 

    It's almost like the 9900 designers knew how to write an instruction set. :) 

     

    Something like: ( Apology in advance. I don't use normal Assemblers often) 

    ZEROEQ     CI   R4,0   * 0=  compare top of stack cache to zero
               CLR  R4 
               JNE  $1
               SETO R4 
    $1         NEXT        * return to Forth

     

    However even though it's only four instructions you can see why a native code compiler would be more efficient on 9900. 

    In MACHFORTH or ASMForth this is only two instructions, compare to zero and the jump.  

    • Like 3
  2. 5 hours ago, Willsy said:

    Been racking my brains to remember why I did it, but came up short. I *thought* I may have done it because it produced faster code, but as Lee has pointed out, it doesn't. Unless I did it under the mistaken assumption that the produced code was faster. The only other thing I can think of is perhaps it made the internal words that calculate jumps (that would be (IF) (THEN) and friends) a little bit shorter? I remember literally scouring the code base looking for ways to save single instructions here and there in order to fit some new word/feature into the 16K ROM space. :dunce:

    Nice to see you back Mark. I suspect life has gotten in the way of the serious job of playing with Forth on a 40 year old machine. 

    • Like 1
  3. 49 minutes ago, OLD CS1 said:

    Per the new Roku user agreement on forced arbitration, I sent a written opt-out to Roku's general counsel.  I included my Roku account information, TV serial number and purchase receipt.  They received it on April 2, 2024.  As of tonight, April 14, 2024, my TCL Roku TV still requires that I accept the agreement in order to use it.

     

    I brought up a support agent on chat, who told me that I could continue using my TV by performing a factory reset, after which I would be limited to live TV and HDMI.  This is not what I understood would be the result of the opt-out.

     

    I am pursuing this further.

    If you can convince a local TV station to do the story that gets people's attention.

    Better if it's a national network station where the story can get distributed across the country. 

     

  4. 3 hours ago, Vorticon said:

    Here's a test program that includes a GCHAR function. I know it seems a bit complicated but I'll make it into a precompiled UNIT which you can include in any program thar requires GCHAR and not worry about the details (at least for now as you get started in your UCSD Pascal journey). I made GCHAR's parameters exactly as TI BASIC expects them, but this could lead to potential confusion in UCSD Pascal where the screen is zero-based. Also GOTOXY has the parameters reversed compared to GCHAR. I'm thinking it would be better if GCHAR was made to take parameters like GOTOXY. 

     

    {gchar test program}
    
    program gchartest;
    uses support;
    
    type
     byte = 0..255;
     
     dual = record
       case boolean of
         true :(val :integer);
         false:(bytes : packed array[0..1] of byte);
     end; (* dual *)
    
    procedure vsbr(vdpadr : integer; byteval : dual); external;
    
    function gchar(y, x : integer) : integer;
    {x : 1..32, y : 1..24}
    
    var
     vdpadr : integer;
     byteval : dual;
     
    begin
     vdpadr := 2048 + (((y - 1) * 32) + (x - 1));
     vsbr(vdpadr, byteval);
     gchar := byteval.bytes[1];
    end; (* gchar *)
    
    begin
     page(output);
     set_screen(2);
     gotoxy(15, 11);
     write('*');
     gotoxy(0, 2);
     write('character code: ',gchar(12, 16));
    end. (* gchartest *)
     

     

    PWORK.dsk 180 kB · 1 download

    Curiosity question.

     

    Is there a way to access the screen management variables in the P-code system?

    Where I am going is; is there any point is seeing what mode the system thinks it is in?  (Text, graphics 1, as the two most common ones) 

    That way your gchar function could maybe know the line length so that 32 would be replaced by a variable that "knows" the current line length. 

     

    Asking for a friend :)

     

     

  5. 7 hours ago, XLERB said:

    Yes, but very out of practice at the moment! Irish tunes are my favorite.

    Cool.  My dad's family comes from a part of Canada with an Irish and French fiddle tradition. I played fiddle badly when I was young.

    I played guitar as a part-time professional for many years.  I just took up Viola last June and joined a community orchestra. 

    Good for old fingers and brains to get some exercise.  But it does cut into my coding time. ;) 

    I am working on some Irish and Scots tunes on Viola. It's a bit harder but some of the tunes sound nice in the lower key. 

    • Like 1
  6. 37 minutes ago, SteveB said:

    I have to admit, when setting up my Linux NAS on a mini-pc last month, I had quite some bash scripts written by ChatGPT. 

     

    It understood very well what I wanted and created code with error-checking and comments, which ran immediately. In some cases I started simple and added features in the dialog ... ignore .zfs directories, write a logfile, ...

     

    It was fun. And spared me from learning the bash syntax, in which I have no real interest in. 

     

    Sounds like the future is coming at us quickly. 

  7. 2 hours ago, Gary from OPA said:

    Great just looked at my WhatsApp and noticed now it has Meta AI inside it and no way to disable it either.

    So does that mean that the CIA can't know what you are talking about...  but Meta can?  :)

     

  8. Well this is fun.  We can extend the range down more than an octave using the bass trick with the noise generator driven by channel 3. 

     

    \    ==================[ BASS VOICE ]==================
    \ Bass voice uses the TENOR oscillator and the noise channel
    \ It also has a lower volume so you have to reduce volume of
    \ the other channels if used in combination 
    
    : PLAY.BASS  ( fcode -- )
            OSC3 OR  SPLIT  SND! SND!  \ send frequency data on channel 3
                31 ATT3 OR  SND!       \ but chan 3 is silent 
    
               -5 OSC4 OR SND!          \ select noise channel for output 
         VOLUME @ ATT4 OR SND!          \ send volume 
                                        \ BASS Note is now playing...    
    
                ON_TIME  @ DELAY   \ set the ISR timer, which auto mutes   
                OFF_TIME @ DELAY   \ time between notes 
    ;
    
    DECIMAL 
    : BASS: ( freq -- )
        CREATE  15 * HZ>CODE ,  \ calibrate freq. & pre-calculate the code 
        DOES> @ PLAY.BASS ;
            
    \ FREQ  NATURAL    FREQ  ACCIDENTAL    EN-HARMONIC
        41 BASS: E1 \ Lowest note of Bass guitar 
        44 BASS: F1    46 BASS: F#1         : Gb0  F#1 ;
        49 BASS: G1	   52 BASS: G#1         : Ab   G#1 ;
        55 BASS: A1	   58 BASS: A#1         : Bb   A#1 ;	
        62 BASS: B1 	 	 	 	 
        65 BASS: C2	   69 BASS: C#2         : Db1  C#2 ;	 
        73 BASS: D2    78 BASS: D#2         : Eb1  D#2 ;	 
        82 BASS: E2 \ Lowest Note of Guitar
        87 BASS: F2	   93 BASS: F#2         : Gb1  F#2 ;	 
        98 BASS: G2	  104 BASS: G#2         : Ab1  G#2 ; 
    
    

     

    • Like 2
  9. In the mean time...

    I finally got something working that I knew was possible but I just didn't get all the pieces right before now.  Maybe I am still learning... ;)

     

    Long ago I made a "language" to write music as text where notes are Forth words that know how to play themselves.

    I added an "expression" feature where you could set how the music was played as in legato (notes connected) staccatto (notes are separated) etc.

    It has dynamics to control the volume. You can set the time signature.  (I don't have a key signature feature and that might just make it more complicated)

    And you can use ||:  <music notes>   :||    to cause a section to repeat which is like real music notation. 

     

    The fractions select the note type. quarter-note, half-note, eighth-note etc. 

     

    Here is Twinkle Twinkle Little Star in the key of A major. 

    : TWINKLE
          120 BPM SOPRANO 
          4/4 NORMAL 
          forte
          | 1/4  A4 A4  E5  E5  | F#5 F#5   1/2 E5 |
          | 1/4  D5 D5  C#5 C#5 | B4  B4    1/2 A4 |
          mf 
          | 1/4  E5 E5  D5  D5  | C#5 C#5   1/2 B4 |
          | 1/4  E5 E5  D5  D5  | C#5 C#5   1/2 B4 | 
          ff
          | 1/4  A4 A4  E5  E5  | F#5 F#5   1/2 E5 |
          | 1/4  D5 D5  C#5 C#5 | B4  B4    1/2. A4 ||
    ;  
    

     

    Anyway that was the easy part. The hard part was that I could never write three parts (melody, harmony, bass for example) and have them all play via the multi-tasker.

    They would always run out of sync.  But this week I finally got it. 

     

    The secret was something I had tried before but over-complicated it a bit.  The idea is to let an interrupt service routine do the timing of the notes and automagically "mute" the sound channel when its timer has expired.  The 2nd helpful thing was to send all the sound bytes for each voice un-interrupted for each voice, meaning don't put a PAUSE in between which changes tasks.

    Then a DELAY function that waits in a loop calling PAUSE to give the other voices time.

    This helped keep everything synchronized. 

     

    Here is the code for the four muting isr timers

     

    Spoiler
    NEEDS DUMP  FROM DSK1.TOOLS
    NEEDS MOV,  FROM DSK1.ASM9900
    
    HERE 
    DECIMAL
    \ isr timer workspace is called MASTER 
    CREATE MASTER  16 CELLS ALLOT   MASTER 16 CELLS 0 FILL 
    
    \ register allocation for 4 TIMER workspace
    \  R0  MASTER CLOCK 
    \  R1  DECREMENTER
    \  R2  DECREMENTER
    \  R3  DECREMENTER
    \  R4  DECREMENTER
    
    \  R5  MUTE1 value   ( used instead of variable)
    \  R6  MUTE2 value
    \  R7  MUTE3 value
    \  R8  MUTE4 value
    
    HEX
    \ Declare timer status registers as constants 
    \ Use them just like normal variables in Forth. (9900 special feature)
    : REGISTER: DUP CONSTANT   CELL+  ;  \ enumerator 
    
    MASTER 
        REGISTER: T0
        REGISTER: T1   \ Soprano voice timer
        REGISTER: T2   \ Alto voice timer
        REGISTER: T3   \ Tenor voice timer
        REGISTER: T4   \ Noise voice timer
        
        REGISTER: MUTE1
        REGISTER: MUTE2
        REGISTER: MUTE3
        REGISTER: MUTE4
    
    : WAIT ( timer -- ) BEGIN DUP @ WHILE  PAUSE  REPEAT DROP ;
    
    : RESET-TIMERS ( -- )  \ preload the workspace :-)
            T1 OFF
            T2 OFF
            T3 OFF
            T4 OFF 
    
    \ mute values kept in registers 
            9F00 MUTE1 ! 
            BF00 MUTE2 ! 
            DF00 MUTE3 ! 
            FF00 MUTE4 ! 
    ;
    
    HEX
    CREATE TIMERISR  ( -- address)
        MASTER LWPI,
        R0 DEC,         \ continous counter for future
    \ Soprano timer
        R1 0 CI, 
        NE IF,
            R1 DEC,
            EQ IF,
                R5  8400 @@ MOVB, \ mute the channel
            ENDIF,
        ENDIF,
    \ Alto timer
        R2 0 CI, 
        NE IF,
            R2 DEC,
            EQ IF,
                R6  8400 @@ MOVB, \ mute the channel
            ENDIF,
         ENDIF,
    \ Tenor timer
        R3 0 CI, 
        NE IF,
            R3 DEC,
            EQ IF,
                R7  8400 @@ MOVB, \ mute the channel
            ENDIF,
        ENDIF,
    \ Noise timer
        R4 0 CI, 
        NE IF,
            R4 DEC,
            EQ IF,
                R8  8400 @@ MOVB, \ mute the channel
            ENDIF,
        ENDIF,
    
        83E0 LWPI,
        RT,
    
    HEX
    : INSTALL ( sub-routine -- )  83C4 ! ;
    
    : COLD    0 INSTALL  COLD ; \ disable interrupts before restarting Forth
    
    HERE SWAP - .  .( bytes)
    
    RESET-TIMERS 
    TIMERISR INSTALL 
    
    
    
    

     

     

    Here is a descant and bassline for Twinkle 

    Spoiler
    : DESCANT
         120 BPM ALTO
       4/4 LEGATO 
       mf
       | 1/8  A3  C#4  B3  A3  E4  A3  C#4 E4 |
       |      F#4 A4   G#4 F#4 E4  A3  C#4 E4 |
       |      D4  F#4  E4  D4  C#4 E4  D4 C#4 |
       |      B3  A4   B4  F#4 E4  F#4 E4 F#4 | 
       piano 
       |      C#4 E4   C#4 E4  D4  E4  D4  E4 |
       |      C#4 E4   C#4 E4  D4  B3  D4  E4 |
       |      C#4 E4   C#4 E4  D4  E4  D4  E4 |
       |      C#4 E4   C#4 E4  D4  B3  D4  E4 |
       forte
       |      A3  C#4  B3  A3  E4  A3    C#4 E4 |
       |      F#4 A4   G#4 F#4 E4  A3    C#4 E4 |
       |      D4  F#4  E4  D4  C#4 E4    D4 C#4 |
       |      B3  E4   F#4 G#4  A4 G#4  1/2 C#4 || 
     ;
    
    : BASSLINE
       120 BPM TENOR
       4/4 MARCATO
       forte
       | 1/2  A2    C#3     | D3      A2     |
       |      E3    A2      | E3      A2     |
       piano 
       | 1/4  A2 A2 D3 D3   | E3  E3  1/2 E3 |
       | 1/4  A2 A2 D3 D3   | E3  E3  1/2 E3 |
       ff
       | 1/2  A2    C#3     | D3        A2   |
       |      E3    A2      | E3   1/2. A2   ||
    ;
    

     

     

    And here is what happens when you run the Forth words in three separate tasks. 

     

     

    Here is the music script player code 

    Spoiler
    \ music lexicon to control the TMS9919 with ISR timers  Apr 2024 B Fox 
    
    \ **********************************************************************
    \               music code MUST be assigned to a task. 
    \               USER variables will crash console task
    \ *********************************************************************
     
    NEEDS DUMP FROM DSK1.TOOLS
    NEEDS HZ   FROM DSK1.SOUND
    NEEDS MASTER FROM DSK1.MUTINGISR \ ISR does timing and mutes sounds
    
    \ ===============  MULTI-TASKING STUFF =======================
    INCLUDE DSK1.MALLOC 
    INCLUDE DSK1.MTASK99 
    
    HEX 2000 H !  \ reset the heap for testing purposes 
    
    \ create a task in heap, fork it, assign Execution token & name 
    : SPAWN ( xt -- pid) USIZE MALLOC DUP>R FORK R@ ASSIGN R>  ;
    
    : TASK: ( xt -- ) ['] PAUSE SPAWN CONSTANT ;
    
    TASK: TASK1 
    TASK: TASK2
    TASK: TASK3 
    TASK: TASK4
    
    \ ===========================================================
    DECIMAL
    \ duration control variables and values
    VARIABLE TEMPO
    
    VARIABLE TIMESIG     \ 2/4 3/4 4/4  6/4
    VARIABLE MEASURE     \ 1 muscial measure of time in ticks (1/60 SECS)
     
    48 USER  VOICE       \ thread local variable 
    50 USER  ON_TIME
    52 USER  OFF_TIME
    54 USER  FEEL        \ controls the on/off time ratio
    56 USER  VOLUME 
    
    : ]T  ( timer# --) CELLS MASTER + ;
    
    \ WAIT is in MUTINGISR.FTH . Waits unto a timer hits zero 
    : DELAY ( n -- ) VOICE @ ]T DUP>R !  R> WAIT  ;
    
    : ]DB ( voice -- ) CELLS MUTE4  + ;  \ 1..4 are valid 
    
    \ need to create a64 bit integer. Forth has the words to do it.
    \ convert a string to double int.   64bits)
    : >DOUBLE  ( addr len -- d ) 0 0 2SWAP >NUMBER 2DROP ;
     
    \ now we create a double int variable called timebase from primitive words
    S" 3600" >DOUBLE  CREATE TIMEBASE  ,  ,
    
    \ no pause for harder realtime control 
    : .HEX ( c) BASE @ >R  HEX . R> BASE !  ;
    
    VARIABLE DEBUG   DEBUG ON 
    HEX 8400 CONSTANT SND_PORT 
    DECIMAL 
    \ no pause for harder realtime control 
    : SND!  ( c --)  S" SND_PORT C!" EVALUATE ;  IMMEDIATE 
    
    : WHOLENOTE ( -- ticks) \ using tempo set the bpm for 1 whole note
          TEMPO @ TIMEBASE 2@  ROT UM/MOD NIP  ( -- ticks for 1 beat )
          TIMESIG @ * DUP  MEASURE ! ;  ( times beats in a bar )
     
    \ Music needs notes to start and end in different ways.
    \ this word adjust the on:off ratio using n
    : EXPRESSION ( note_dur n --)
          OVER SWAP -  TUCK -   ( -- on-ms off-ms )
          ( 1 MAX) OFF_TIME !
          ( 1 MAX) ON_TIME ! ;    \ store times in variables
                                     
    \ return full duration of current note
    : NOTE      ( -- MS ) ON_TIME @ OFF_TIME @ + ;
    
    : DURATION! ( MS -- )  FEEL @ EXPRESSION ;
     
    : 5%       ( -- ) 5 / ;
    : 10%      ( n -- n ) 10 / ;
    : 20% ( n -- n ) 20 / ;
    : 50%       ( N -- N/2) POSTPONE 2/ ; IMMEDIATE 
    : %         ( N N2  -- N%) 100 */ ;    \ calculate n2% of n
    : 50%+      ( N -- N+50%)  DUP 50% + ; \ dotted notes have 50% more time
    
    \ === BAR LINES ===
    : | ;  ( noop at this times )
    : ||    MYSELF SLEEP  PAUSE  ;  \ DOUBLE bar line ends the music 
    
    
    : PLAY      ( fcode -- )
                OSC @ OR  SPLIT  SND! SND!  \ send frequency 
       VOLUME @ ATT @ OR SND!               \ send volume 
                                            \ Note is now playing...            
    
    \ DELAY function loads timer register. ISR begins decrementing. 
    \ DELAY monitors timer register and runs PAUSE while waiting 
                ON_TIME  @ DELAY   \ set the ISR timer, which auto mutes   
                OFF_TIME @ DELAY   \ time between notes 
    ;
    
    \ note object creator
    : NOTE:   ( freq -- )
               CREATE         \ compile time: create a name in the dictionary
                     HZ>CODE , \ compile the 9919 code into the note
     
               DOES> @ PLAY ; \ run time:  fetch the number, play the note
    
    
    \ ================[ API ]==============================
    : SOPRANO   1 VOICE ! GEN1 ; SOPRANO 
    : ALTO      2 VOICE ! GEN2 ;
    : TENOR     3 VOICE ! GEN3 ;
    
    : 4/4    4 TIMESIG ! ;  4/4 
    : 3/4    3 TIMESIG ! ;
    : 2/4    2 TIMESIG ! ;
    
    : 2X    2 0  ;
    
    \ repeat bars  
    : ||:      POSTPONE 2X POSTPONE DO  ; IMMEDIATE 
    : :||      POSTPONE LOOP ; IMMEDIATE 
    
    \ dynamics 
    
    : ff        0  VOLUME ! ;
    : forte     2  VOLUME ! ;
    : mf        4  VOLUME ! ;
    : piano     6  VOLUME ! ;
    : pp        8  VOLUME ! ;
    
    
    \ FREQ  NATURAL    FREQ  ACCIDENTAL    EN-HARMONIC
    \ -------------    ----------------   ----------------
      110 NOTE: A2     117 NOTE: A#2       : Bb2 A#2 ;
      131 NOTE: C3     139 NOTE: C#3       : DB3 C#3 ;
      147 NOTE: D3     156 NOTE: D#3       : Eb3 D#3 ;
      165 NOTE: E3
      175 NOTE: F3     185 NOTE: F#3       : Gb3 F#3 ;
      196 NOTE: G3     208 NOTE: G#3       : Ab3 G#3 ;
      220 NOTE: A3     233 NOTE: A#3       : Bb3 A#3 ;
      247 NOTE: B3
      262 NOTE: C4     277 NOTE: C#4       : Db4 C#4 ;
      294 NOTE: D4     311 NOTE: D#4       : Eb4 D#4 ;
      330 NOTE: E4
      349 NOTE: F4     370 NOTE: F#4       : Gb4 F#4 ;
      392 NOTE: G4     415 NOTE: G#4       : Ab4 G#4 ;
      440 NOTE: A4     466 NOTE: A#4       : Bb4 A#4 ;
      494 NOTE: B4
      523 NOTE: C5     554 NOTE: C#5       : Db5 C#5 ;
      587 NOTE: D5     622 NOTE: D#5       : Eb5 D#5 ;
      659 NOTE: E5
      698 NOTE: F5     740 NOTE: F#5       : Gb5 F#5 ;
      784 NOTE: G5     831 NOTE: G#5       : Ab5 G#5 ;
      880 NOTE: A5     932 NOTE: A#5       : Bb5 A#5 ;
      988 NOTE: B5
     1047 NOTE: C6
    
    : BPM       ( BPM -- )  \ set tempo in beats per minute
                TEMPO !
                WHOLENOTE DURATION! ;
     
    : NORMAL      NOTE 4 % FEEL ! ;
    : LEGATO      NOTE 0 FEEL ! ;    \ notes run together
    : STACCATTO   NOTE 9 % FEEL ! ;  \ short notes
    : MARCATO     NOTE 6 % FEEL ! ;  \ march feel
     
    : RIT.     NOTE DUP 20% + DURATION! ;
    
    : 1/1      WHOLENOTE      DURATION! ;
    : 1/2      WHOLENOTE 50%  DURATION! ;
    : 1/2.     1/2  NOTE 50%+ DURATION! ;
    : 1/4      1/2  NOTE 50%  DURATION! ;
    : 1/4.     1/4  NOTE 50%+ DURATION! ;
    : 1/8      1/4  NOTE 50%  DURATION! ;
    : 1/8.     1/8  NOTE 50%+ DURATION! ;
    : 1/16     1/8  NOTE 50%  DURATION! ;
    : 164     1/16 NOTE 50%  DURATION! ;
    : REST     NOTE DELAY ;
    \ =================================================================
    \ Usage Demonstrations
    \ This system makes sense if you understand traditional music notation.
     
    : TWINKLE
          120 BPM SOPRANO 
          4/4 NORMAL 
          forte
          | 1/4  A4 A4  E5  E5  | F#5 F#5   1/2 E5 |
          | 1/4  D5 D5  C#5 C#5 | B4  B4    1/2 A4 |
          mf 
          | 1/4  E5 E5  D5  D5  | C#5 C#5   1/2 B4 |
          | 1/4  E5 E5  D5  D5  | C#5 C#5   1/2 B4 | 
          ff
          | 1/4  A4 A4  E5  E5  | F#5 F#5   1/2 E5 |
          | 1/4  D5 D5  C#5 C#5 | B4  B4    1/2. A4 ||
    ;  
    
    : DESCANT
         120 BPM ALTO
       4/4 LEGATO 
       mf
       | 1/8  A3  C#4  B3  A3  E4  A3  C#4 E4 |
       |      F#4 A4   G#4 F#4 E4  A3  C#4 E4 |
       |      D4  F#4  E4  D4  C#4 E4  D4 C#4 |
       |      B3  A4   B4  F#4 E4  F#4 E4 F#4 | 
       piano 
       |      C#4 E4   C#4 E4  D4  E4  D4  E4 |
       |      C#4 E4   C#4 E4  D4  B3  D4  E4 |
       |      C#4 E4   C#4 E4  D4  E4  D4  E4 |
       |      C#4 E4   C#4 E4  D4  B3  D4  E4 |
       forte
       |      A3  C#4  B3  A3  E4  A3    C#4 E4 |
       |      F#4 A4   G#4 F#4 E4  A3    C#4 E4 |
       |      D4  F#4  E4  D4  C#4 E4    D4 C#4 |
       |      B3  E4   F#4 G#4  A4 G#4  1/2 C#4 || 
     ;
    
    : BASSLINE
       120 BPM TENOR
       4/4 MARCATO
       forte
       | 1/2  A2    C#3     | D3      A2     |
       |      E3    A2      | E3      A2     |
       piano 
       | 1/4  A2 A2 D3 D3   | E3  E3  1/2 E3 |
       | 1/4  A2 A2 D3 D3   | E3  E3  1/2 E3 |
       ff
       | 1/2  A2    C#3     | D3        A2   |
       |      E3    A2      | E3   1/2. A2   ||
    ;
    
    
    ' TWINKLE   TASK1 ASSIGN 
    ' DESCANT   TASK2 ASSIGN
    ' BASSLINE  TASK3 ASSIGN 
    
    MULTI 
    
    : TEST3      TASK1 RESTART  TASK2 RESTART  TASK3 RESTART  ;
    : WITHBASS   TASK1 RESTART  TASK3 RESTART ;
    
    
    

     

     

    • Like 4
  10. 12 hours ago, Lee Stewart said:

    One of my TODOs is to possibly change BRANCH and 0BRANCH to use absolute addresses (per @Willsy’s TurboForth) instead of an offset (per figFORTH/TI Forth/fbForth), but I really do not see the advantage except, possibly, at compile time, which does not seem that important. The difference at execution time is

           MOV  *IP,IP       <---IP is a register

    versus

           A    *IP,IP       <---IP is a register

    which take exactly the same amount of time, as far as I can tell. So, unless someone (@Willsy@Tursi? @matthew180? @jedimatt42? @apersson850? @TheBF? ??) can show me a significant difference in execution time, I am inclined to leave sleeping dogs lie—the mod would be significant!

     

    ...lee

    I did a similar study a while back and saw no advantage to changing to  absolute addresses and in fact if you wanted to relocate binary images of Forth code it's one less thing to worry about when you use relative branching. 

     

    • Thanks 2
  11. 1 hour ago, mizapf said:

    Congratulations!

     

    The camera obviously pulled up the brightness; it should have been a lot darker. Isn't it a spooky atmosphere when you look around and see the orange horizon, and above you this weird spectacle with the dark sun and the white corona in a deep blue sky, and then you notice there are stars and planets, maybe Venus or even Mercury?

     

    In the time before the totality, the eyes can easily adapt to the weaker light, and you don't notice that 80%, 90%, or 95% of the sun are eclipsed. Everything around seems to cast hard shadows, as the light source is getting smaller. Around 98% you feel like wearing sunglasses, and it's not like a sunset where you have diffuse lighting. But when the totality comes, the light suddenly dims down like in a movie theater just before the curtain opens.

    Exactly.  That's a good description. 

    My son in law took that picture with his phone so ya, auto exposure.

  12. When you see Forth code written by a master it's always an eye-opener to me. 

    Here is number convertor written by Mitch Bradley for his CForth which is a Forth system based on his Open Firmware.

    Open Firmware is a byte-code Forth that was used to boot Apple Power PC computers and Sun workstations.

    I think some Linux distros use it too. Mitch has been writing Forth a looooong time. 

    I made one of these and it was only for HEX and used way more code. :) 

     I am putting this on in my system with the license info. 

     

    EDIT: I have to find out what COMPILE-WORD does in Cforth. 

     

    Spoiler
    The following license terms apply to the FirmWorks C Forth system
    contained in this directory tree.
    -----------------------------------------------------------------
    Copyright (c) 2008 FirmWorks
     
    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
    "Software"), to deal in the Software without restriction, including
    without limitation the rights to use, copy, modify, merge, publish,
    distribute, sublicense, and/or sell copies of the Software, and to
    permit persons to whom the Software is furnished to do so, subject to
    the following conditions:
    
    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.
    

     

     

    \ --------------------
    \  H#                           ( "hexnumber" -- n )
    \     Get the next word in the input stream as an unsigned hex
    \     single-number literal. (Adopted from Open Firmware.)
    
    \ Temporary hex, and temporary decimal.  "h#" interprets the next word
    \ as though the base were hex, regardless of what the base happens to be.
    \ "d#" interprets the next word as though the base were decimal.
    \ "o#" interprets the next word as though the base were octal.
    \ "b#" interprets the next word as though the base were binary.
    
    DECIMAL
    : #:  \ name  ( base -- )  \ Define a temporary-numeric-mode word
       CREATE   , IMMEDIATE
       DOES>  BASE @ >R 
              @ BASE !  
              PARSE-WORD COMPILE-WORD 
              R> BASE !
    ;
    
    16 #: H#	\ Hex number
    10 #: D#	\ Decimal number
     8 #: O#	\ Octal number
     2 #: B#	\ Binary number
    

     

  13. 1 hour ago, Lee Stewart said:

    Regarding booting up fbForth with its ISR disabled, I will have PLAY , STREAM , SAY check for a cleared ISR hook (>83C4) and, upon seeing it cleared, exit the routine immediately. Do you think I should include a message such as, “ISR not active!” or just fail quietly?

     

    ...lee

    There is some S/W principle I have read that is something like "Do the expected thing". 

    So I think a message is order since it will happen at run-time no? 

    You could save a couple of bytes with "ISR missing" or "Bad ISR"  ?? 

    • Like 2
  14. North shore of lake Erie with the grandkids was amazing. My first total eclipse.  

    We got very lucky. Stormy morning but it cleared mostly by 2:30 PM. 

     

    Drive home was nuts.  2.5 hours for a 50 minute trip.  Everybody stole my idea! :) 

     

    Lake Erie April 2024.jpg

    • Like 2
    • Thanks 1
  15. Here is piece of N. American history that is mostly forgotten.

    My mother told me about a massive changeout of electrical equipment when Ontario Canada (a province) and New York state ,which is on the other side of Niagara falls,

    changed from 25Hz to 60Hz.

    As I recall she said you either replaced your old equipment or there was a program to have techs come to your home and change motors and transformers.

     

    And the internet even backs up my mother's story. 

    https://www.lifebynumbers.ca/history/the-rise-and-fall-of-25-cycle-hz-electricity-in-ontario/

    • Like 2
  16. 1 hour ago, Gary from OPA said:

    BREAKING REPORT: ⚠️ Massive container ship loses power near NYC’s Verrazzano Bridge..

    DEVELOPING..

    A giant container ship experienced a power outage in the waters near New York City and was safely anchored close to the Verrazzano-Narrows Bridge on Friday night.

    This incident occurred shortly after a similar situation with another large cargo ship led to a collision with Baltimore's Francis Scott Key Bridge less than two weeks earlier.

    The US Coast Guard verified that their Vessel Traffic Service was alerted to the 89,000-ton M/V Qingdao losing its propulsion around 8:30 p.m. while navigating through the Kill Van Kull waterway, which is the maritime passage between Staten Island and Bayonne, New Jersey.

    20240407_191303.jpg

    Foreign ships should probably not be allowed in these waters without engineering inspections. 

    It's a very big strategic risk to the USA. 

     

    One Canuck's opinion. :) 

     

     

    • Like 1
  17. 15 minutes ago, Tursi said:

    Don't attach televisions to the internet. They are just going to keep using that connection as a reason to own you.

     

    You want Streaming, just buy a $50 PC and drop it behind the TV. Run the OS of your choice - even Windows is less intrusive than TVs are becoming. Use a wireless mouse and keyboard or even a cell phone remote (I like "Unified Remote" on Android). Done, and more flexible to boot. That PC will cover your emulation needs too ;)

     

    If a TV wants to display ads on your paused screens in that scenario, I guess they could, but they aren't going to be able to download them.

     

    Any TV that refuses to operate without an internet connection should be returned, they won't get the point otherwise.

     

    Also if you still "need" to watch commercial TV it's being broadcast in High-definition and can be watched for free with your "offline" TV with a $50.00 Antenna.

    I have encountered a lot of people who don't know that broadcasting TV still exists. (not sure for how much longer however) ;)

     

×
×
  • Create New...