Otrona Attaché

Post Reply
User avatar
RobertK
Well known member
Posts: 410
Joined: Mon Feb 26, 2018 12:58 pm

Otrona Attaché

Post by RobertK »

I'm starting this thread for discussions on this wonderful portable CP/M machine with high-res graphics and PSG sound.

First question: is there a way to disable the keyboard click sound?

The technical manual only mentions on page 3-52 that the "60 Hz Interrupt" is responsible for creating the click sounds, but gives no details on how to disable them programmatically.
User avatar
dom
Well known member
Posts: 2304
Joined: Sun Jul 15, 2007 10:01 pm

Re: Otrona Attaché

Post by dom »

From this bit of the doc:
Screenshot 2024-10-06 at 21.10.00.png
It looks you can do it via escape codes (See 3-38), so I'm guessing ESC @ 0x09 0x00 might do it? Try it without --generic-console so it goes directly to the BDOS.
You do not have the required permissions to view the files attached to this post.
User avatar
RobertK
Well known member
Posts: 410
Joined: Mon Feb 26, 2018 12:58 pm

Re: Otrona Attaché

Post by RobertK »

Ok, so that must be

printk("\x1b\x40\x09\x00");

Unfortunately, this has no effect.

For experimenting, dstar.c can be used:

zcc +cpm -subtype=attache -create-app -Dspritesize=20 -D__ATTACHE__ -o dstar dstar.c

But I think it will be easier to first get it to work in Basic, there is MBASIC on the Otrona system disk oattache.td0.

So I tried

print chr$(27);"@90"

but to no avail.
stefano
Well known member
Posts: 2328
Joined: Mon Jul 16, 2007 7:39 pm

Re: Otrona Attaché

Post by stefano »

You could try with bdos(4,27); bdos(4,64); bdos(....

EDIT: IT'S 2 (CPM_WCON), NOT 4. you also need to include arch/cpm.h. I'm going to try this myself, we could thik at a set of macros to quickly add something.

BTW I'm not sure the basic syntax you used is correct, you passed the ASCII values for the number values

Better to use a sequence like PRINT ASC(27); ASC(64)...
stefano
Well known member
Posts: 2328
Joined: Mon Jul 16, 2007 7:39 pm

Re: Otrona Attaché

Post by stefano »

Well, this is an odd one !
I think it could have worked with BDOS, but I ended up trying with BIOS before discovering what was going on.

#include <cpm.h>

// Set the keyboard click
#define attache_kbclick(a) {bios(BIOS_CONOUT,27,0);bios(BIOS_CONOUT,64,0);bios(BIOS_CONOUT,9,0);bios(BIOS_CONOUT,a,0);}


The values act as described in the documentation BUT, you first need to reboot your emulated system. MAME remembers the CMOS status and will, in example, stay silent forever :D
stefano
Well known member
Posts: 2328
Joined: Mon Jul 16, 2007 7:39 pm

Re: Otrona Attaché

Post by stefano »

There COULD actually be a way to temporairly tamper the running BIOS.

WBOOT: DI
MVI A,0FFH
STA VALSTP ; INHIBIT VALET AT THIS POINT
(...)


; VARIABLES FOR EXTERNAL USE
;
WSFLAG: .BYTE 0
VALSTP: .BYTE 0FFH <<<-------------------------------------------------
DSKFLG: .BYTE 0FFH
VALPND: .BYTE 0
CLIKAD: .WORD CLICK <<<-------------------------------------------------
VALCMD: .BYTE 0
VALTIM: .BYTE 0
;
; VECTORS
;
JMP OUTBLK
JMP CLNVAL
JMP ADJPNT ; READ CMOS & CHANGE PRINT BAUD
JMP ADJCOM ; READ CMOS & CHANGE COMM. BAUD
JMP DOBOOT ; DO WARM BOOT BUT DON'T GO TO CCP
JMP GOCPM ; INITIALIZE ENVIRONMENT
JMP CMPOFF ; RETURN HL W/PROPER LINE OFFSET
WBTVEC: JMP CCP+3 ; USED TO REDIRECT WARM BOOT CCP JUMP
;
; MORE VARIABLES
;
SIORG5: .BYTE 0EAH ; INITIAL STATUS OF COMM. PORT RR 5
SPOOL: .BLKB 1 ; USED IN BANKED SYSTEM FOR SPOOLER
PARPNT: .WORD CURCHR
LINOFS: .BYTE 0
DSPFLG: .BYTE 0
ALMWAT: .BYTE 0
ALMCNT: .BYTE 0 ; COUNTS # OF ALARM TONES
BNKFLG: .BYTE 0 ; FLAG FOR BANKED OR UNBANKED
ALMFLG: .WORD 600 ; BIOS
VALTON: .WORD NOTONE <<<-------------------------------------------------
CLKFLG: .BYTE 0
TIMFLG: .BYTE 0FFH
NUMFLG: .BYTE 0
KEYADR: .WORD KEYTBL <<<<<<<<<<<<<<<<<<<
FLPTBL: .WORD FMTTBL
DSTMP: .WORD 1019H ; DATE STAMP


It's rather a mess, but probing the BIOS and using relative pointers might work. (I haven't succeeded so far)
User avatar
RobertK
Well known member
Posts: 410
Joined: Mon Feb 26, 2018 12:58 pm

Re: Otrona Attaché

Post by RobertK »

stefano wrote: Mon Oct 07, 2024 5:19 pm #include <cpm.h>

// Set the keyboard click
#define attache_kbclick(a) {bios(BIOS_CONOUT,27,0);bios(BIOS_CONOUT,64,0);bios(BIOS_CONOUT,9,0);bios(BIOS_CONOUT,a,0);}


The values act as described in the documentation BUT, you first need to reboot your emulated system. MAME remembers the CMOS status and will, in example, stay silent forever :D
That was it, thank you! I have added this piece of information to the wiki page.
I think this solution should be good enough - although some Attaché owners might be annoyed by my programs switching off the keyboard sounds which they prefer to hear. ;-)
stefano
Well known member
Posts: 2328
Joined: Mon Jul 16, 2007 7:39 pm

Re: Otrona Attaché

Post by stefano »

I noticed looking at the bios listing that the attachè should have a 'valet' key, presumably to allow the operator to change the console behaviour on the fly.
I couldn't understand how to enter in valet mode with MAME though.
stefano
Well known member
Posts: 2328
Joined: Mon Jul 16, 2007 7:39 pm

Re: Otrona Attaché

Post by stefano »

First of all, direct BIOS calls are a must, otherwise the BDOS would catch some of the values preventing them to reach the console driver.

The Otrona BIOS source listing was donated to PD by Otrona in 1984 and published as a Christmas present by Roger Doger.
Looking at it we I discovered that the environment variables for the keyboard click are in a rather peculiar position which can hardly evolve in possible different BIOS versions (those variables are in spare spaces in the Interrupt vector !!).

Note V60HZ, it can be used to trap the interrupt.

Code: Select all

;
;	RESERVED FOR 3 INTERRUPT VECTORS (I=0DAH)
;
; 0xDA62
;
INT1:	.BLKB	2
INT2:	.BLKB	2
INT3:	.BLKB	2
;
;	JUMP TABLE FOR EXTERNAL USE
;
JMPTBL: JMP	DISK	; VECTOR TO DISK
	JMP 	DISPLY	; VALET CRTOUT
	JMP	TTYIST	; TEST COMM. INPUT STATUS
	JMP	TTYIN	; INPUT FROM COMM.
	JMP	TTYOUT	; OUTPUT TO COMM.
	JMP	SOUND	; TABLE DRIVEN SOUND
	JMP	PUTVAL	; EXIT VALET OVERLAY
	JMP	LINDSP+3; FOR BASIC GRAPHICS
;
;
;	VARIABLES FOR EXTERNAL USE
;
; 0xDA80
;
WSFLAG:	.BYTE	0
VALSTP:	.BYTE 	0FFH
DSKFLG:	.BYTE	0FFH
VALPND:	.BYTE	0
CLIKAD: .WORD	CLICK
VALCMD:	.BYTE	0
VALTIM:	.BYTE	0
;
;	VECTORS
;
; 0xDA88
	JMP	OUTBLK
	JMP	CLNVAL
	JMP	ADJPNT	; READ CMOS & CHANGE PRINT BAUD
	JMP	ADJCOM	; READ CMOS & CHANGE COMM. BAUD
	JMP	DOBOOT	; DO WARM BOOT BUT DON'T GO TO CCP
	JMP	GOCPM	; INITIALIZE ENVIRONMENT
	JMP	CMPOFF	; RETURN HL W/PROPER LINE OFFSET
WBTVEC:	JMP	CCP+3	; USED TO REDIRECT WARM BOOT CCP JUMP
;
;	MORE	VARIABLES
;
; 0xDAA0
SIORG5:	.BYTE	0EAH	; INITIAL STATUS OF COMM. PORT RR 5	
SPOOL:	.BLKB	1	; USED IN BANKED SYSTEM FOR SPOOLER
PARPNT:	.WORD	CURCHR
LINOFS:	.BYTE	0
DSPFLG:	.BYTE	0
ALMWAT:	.BYTE	0
ALMCNT:	.BYTE	0	; COUNTS # OF ALARM TONES
BNKFLG:	.BYTE	0	; FLAG FOR BANKED OR UNBANKED
ALMFLG:	.WORD	600	; BIOS
; 0xDAAB
VALTON:	.WORD	NOTONE
; 0xDAAD
CLKFLG:	.BYTE	0
TIMFLG:	.BYTE	0FFH
NUMFLG:	.BYTE	0
; 0xDAB0
KEYADR:	.WORD	KEYTBL
FLPTBL:	.WORD	FMTTBL
DSTMP:	.WORD	1019H	; DATE STAMP
; 0xDAB6
	.IFN	TPI,[
	.BYTE	96
]
	.IFE	TPI,[
	.BYTE	48
]
	.BLKB	1	; FREE FOR USE
;
;|-----------------------------------|
;| INTERRUPT VECTORS - MUST BE ON A  |
;| BOUNDARY OF AN EVEN MULTIPLE OF 8 |
;|-----------------------------------|
;
	.BLKB	2	; RESERVED FOR CTC CH. 0
	.BLKB	2	; RESERVED FOR CTC CH. 1
V60HZ:	.WORD	SRV60	; 60 HZ TIMER (CTC CH. 2)
	.WORD	SRVFPY	; FLOPPY INT. (CTC CH. 3)
	
This is how to temporairly alter the keyboard click without affecting the CMOS settings, we alter the table pointed by CLIKAD.


int reset_kbclick() {
#asm
ld de,($da84) ; usually 'CLICK', but it depends on the CMOS settings
ld hl,NOTONE
ld bc,15
ldir
ret

NOTONE:
defb 00,00,00,00,0x0F,0x0F,0x0F,0x0FF,00,00,00,00,00,00,00

#endasm
}


The BIOS includes also the following sound tables:

;CLICK:
; defb 01,04,00,00,0x0F,0x0F,0x0F,0x00,0x80,0x47,0x1D,0x20,0x0F6,0x0AF,0x0ED
;BEEP:
; defb 02,02,00,00,0x0F,0x0F,0x0F,0x32,0x54,0x20,0x32,0x56,0x20,0x3E,0x25
;MIDA:
; defb 02,00,00,00,0x0F,0x0F,0x0F,0xF8,0x1F,00,0xFE,00,00,00,00
;AUP3O:
; defb 02,00,00,00,0x0F,0x0F,0x0F,0xF8,0x1F,02,0xFA,00,00,00,00
;BELLTN:
; defb 02,02,00,00,0x0F,0x0F,0x0F,0x32,0x54,0x20,0x32,0x56,0x20,0x3E,0x25


We have 2 different way to use this trick, to just patch the BIOS at runtime (as in the example above, which makes the change effective until the next reboot), or to provide a temporary sound table to point to and restore the original pointer on exit.


Note that if the audio volume is OFF then no sound would be produced (unless we find a temporary setting for this, too).
Apparently interesting effects can be created enabling the noise generator..
stefano
Well known member
Posts: 2328
Joined: Mon Jul 16, 2007 7:39 pm

Re: Otrona Attaché

Post by stefano »

I got a nice function for it, to be pulled tonight.
stefano
Well known member
Posts: 2328
Joined: Mon Jul 16, 2007 7:39 pm

Re: Otrona Attaché

Post by stefano »

The new function can be used to disable the keyboard click with just kbd_click(0), otherwise a ptr pointing to a 15 byte data sequence for the PSG allows either standard or fancy sound effects.

I'm not sure the same approach works for the volume level, the BIOS portion dealing with it in the tail and could have been moved in the different OS versions.

Code: Select all



#include <stdio.h>
#include <stdlib.h>
#include <arch/attache.h>

char value[30];

main()
{

printf("If you don't hear key clicks, reboot the system now.\n");

cmos_volume(12);
cmos_kbclick(2);

kbd_click(0);

	while(1) {
		printf("KBD tone?  ");
		gets(value);

		switch (atoi(value))
		{
			case 0:
				kbd_click(0);
				break;
			case 1:
				kbd_click(KBD_CLICK);
				break;
			case 2:
				kbd_click(KBD_BEEP_LO);
				break;
			case 3:
				kbd_click(KBD_BEEP_HI);
				break;
			case 4:
				kbd_click(KBD_SND_LO);
				break;
			default:
				exit (0);
				break;
		}
	}
}


EDIT: the 'VALET" application is part of the BIOS. to enable it you need to type CTRL-ESC. On MAME ESC probably needs to be remapped to another key. Or with enter_valet() ;)
stefano
Well known member
Posts: 2328
Joined: Mon Jul 16, 2007 7:39 pm

Re: Otrona Attaché

Post by stefano »

I noticed that the Attachè emulation is still rather weak.
The latest emulator version includes the i86 CPU but fails booting:
https://mametesters.org/view.php?id=8905

The ESC console sequence, supposed to provide graphics functionalities, doesn't enable the graphics mode.

I tried few workarounds for this (BIOS, BDOS..), none worked.

Yet another fancy workaround:

Code: Select all

#include <stdio.h>
#include <cpm.h>

#pragma redirect fputc_cons=attache_putc

extern char __LIB__ attache_putc (char c);

extern char attache_putc (char c) {
#asm
	pop hl
	pop bc
	push bc	; c=character to print
	push hl
	jp 0xDA6B
#endasm
}


User avatar
RobertK
Well known member
Posts: 410
Joined: Mon Feb 26, 2018 12:58 pm

Re: Otrona Attaché

Post by RobertK »

stefano wrote: Tue Oct 08, 2024 4:43 pm The new function can be used to disable the keyboard click with just kbd_click(0)
Thank you, I can confirm that when using this function, the sound is back on again after restarting MAME. I have updated the wiki page.
stefano
Well known member
Posts: 2328
Joined: Mon Jul 16, 2007 7:39 pm

Re: Otrona Attaché

Post by stefano »

You're welcome. I'm pulling also clock() and time().
otrona_clock.png
You do not have the required permissions to view the files attached to this post.
stefano
Well known member
Posts: 2328
Joined: Mon Jul 16, 2007 7:39 pm

Re: Otrona Attaché

Post by stefano »

I'm adding a hint in the wiki, the recent MAME versions fail the first floor disk boot attempt, but you can kick the emulator and step over.
The MAME team recently suggested to "press F3 to reset the system", but since the F3 key is bound to the keyboard emulation you first need to press 'right ALT' and enable the partial keyboard emulation.
Thus, after launching the emulator, wait for the ROM BIOS message, then press right ALT, F3, and right ALT again if you need the full keyboard emulation. While you are on it you can also press TAB, enter the emulator menu, and remap the ESC key to something different to be able to type CTRL-ESC without being intercepted by the operating system.
Post Reply