Modifying the Orchestra-90 Software

2024-06-02 | [retrocomputing] [trs80]

Two reasons I needed to do this:

  1. The card I made uses the unused Tandy ports 0x8e and 0x8f on the graphics header instead of 0x75 and 0x79, and with a non-inverted D7.
  2. If you want to make a jukebox-like setup that plays a bunch of files, you can't use JCL (batch files) because the ORCH90/CMD program uses it's own keyboard driver.

Problem 1 is pretty easy, just find an OUT (0x75) and OUT (0x79) instruction in the code, and change it to my addressing. Actually, I had to put a jump in there, so I could do an XOR 0x80 and un-invert the D7 bit.

Problem 2 is slightly more difficult, since I did not know much about the internals of the program. It has been done before, for the Model 1 Orchestra-85, but I ended up dong a lot of poking around in the trs80gp debugger, looking at trace files, and using a disassembler.

Firstly, it helps to know what types of things JCL can control. From the LDOS 5.1 manual for the Model 3:

@KEYIN .... (Vector = X'0040')
------------------------------
This routine will accept a line of input until terminated  by  either an
<ENTER> or <BREAK>.  During  the  input, the routine  will  display  the
entries. Backspace, tab, line delete, and 32 cpl mode are supported.

    HL => user line buffer of length = B+1
    B => maximum number of characters to input
    HL <= points to buffer start
    B <= the actual number of characters input
    CF <= set if <BREAK> terminated the input

...

All programs that utilize the line input handler (identified as  @KEYIN in the
System Entry Point section) will be able to  accept  "keyboard" input from the
JCL file, just as though you typed it in when the program  was run.

So as long as your program has a line-based input, and calls the system 0x0040 when it does input, you can use a JCL script to interact with it. The ORCH90 program does not do this, probably because it has it's own built-in editor, which seems easier to write if you control all the pieces. I found out that the thing that reads the commands in ORCH90 just picks the character right off the screen from VRAM. It is also easy to hijack your way into a loop off the main loop if you can find somewhere to get in. I shortened some of the title screen to make room:


        DB      00h
        DB      00h
        DB      0D0h
        DB      "OVERLAP? ORCHESTRA-90 (tm) Software Affair, Ltd."
        DB      80h
        DB      "(C)1981/2/3 Jon Bokelman"
        DB      80h
        DB      "Licensed Tandy"
        DB      80h
        DB      "Version 01.0P.GS"
        DB      80h
        DB      00h
LCHB: ;mod for alnwlsn grafyx dac - channel B
        ADD     A,(HL)
        XOR     0x80
        OUT     (142),A
        jp 6BB6h
LCHA: ;mod for alnwlsn grafyx dac - channel A
        ADD     A,(HL)
        XOR     0x80
        OUT     (143),A
        jp 6B8Ah
new62a1: ;new loop which runs the command entry line with system line entry handler
        ld hl,0x4020 ;put system cursor back at the top left of the screen
        ld de,0x3C00
        ld (hl),e
        inc hl
        ld (hl),d
        ld a,16 ;max 16 characters (probably enough)
        ld b,a
        ld hl,0x5d5a ;put buffer somewhere we don't care about (reads directly from screen)
        call 0x0040 ;system routine to input line
        ld hl,0x3c00 ;where command reader should read from (first char)
        call 0x63b3 ;call orchestra90 command reader
        call 0x5e22 ;clear command input line
        jp new62a1
        DB      2Fh             ; '/'
        DB      43h             ; 'C'
        DB      4Dh             ; 'M'

Also, don't forget to make the needed jump/call changes:


L5F4E:  LD      (L5CD4),A
        BIT     1,(IX+0Fh)
        CALL    NZ,L5EAE
        LD      (IY+3Fh),80h
        CALL    new62a1 ;<<<<<<<<<<<<<<<<<<<<<<<
        LD      HL,5F51h
        PUSH    HL
        LD      HL,5CD4h
        SET     1,(HL)
    ...

L6B7D:  LD      DE,0000h
        ADD     HL,DE
        LD      (L6B7D+1),HL
        LD      L,H
L6B85:  LD      H,00h
        JP LCHA ;<<<<<<<<<<<<<<<<<<<<<<<
L6B8A:  LD      HL,(L5938)
L6B8D:  LD      DE,0000h
        ADD     HL,DE
        LD      (L6B8D+1),HL
        LD      L,H
L6B95:  LD      H,00h
        LD      A,(HL)
L6B98:  LD      HL,(L5938)
L6B9B:  LD      DE,0000h
        ADD     HL,DE
        LD      (L6B9B+1),HL
        LD      L,H
L6BA3:  LD      H,00h
        ADD     A,(HL)
L6BA6:  LD      HL,(L5938)
L6BA9:  LD      DE,0000h
        ADD     HL,DE
        LD      (L6BA9+1),HL
        LD      L,H
L6BB1:  LD      H,00h
        JP LCHB ;<<<<<<<<<<<<<<<<<<<<<<<
        DJNZ    L6B6C
        EXX
        DJNZ    L6B5C
        DEC     D
        JR      NZ,L6B5B
        JP      L6B3F
    ...

Now, in your JCL you can do something like:

ORCH90/CMD
G SONG1
G SONG2
G SONG3
QUIT

and it will load and play them in sequence when you DO YOURJCL/JCL.

comments | Alnwlsn 2024