Otrona Attaché
Otrona Attaché
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.
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.
Re: Otrona Attaché
From this bit of the doc:
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.
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.
Re: Otrona Attaché
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.
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.
Re: Otrona Attaché
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)...
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)...
Re: Otrona Attaché
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
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

Re: Otrona Attaché
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)
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)
Re: Otrona Attaché
That was it, thank you! I have added this piece of information to the wiki page.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![]()
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. ;-)
Re: Otrona Attaché
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.
I couldn't understand how to enter in valet mode with MAME though.
Re: Otrona Attaché
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.
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..
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)
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..
Re: Otrona Attaché
I got a nice function for it, to be pulled tonight.
Re: Otrona Attaché
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.
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()
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()

Re: Otrona Attaché
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:
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
}
Re: Otrona Attaché
You're welcome. I'm pulling also clock() and time().
You do not have the required permissions to view the files attached to this post.
Re: Otrona Attaché
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.
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.