2024-06-02 | [retrocomputing] [trs80]
Two reasons I needed to do this:
0x8e
and 0x8f
on the graphics header instead of 0x75
and 0x79
, and with a non-inverted D7.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
.