6809 Assembly programming for
the Fujitsu FM-7
The FM-7 is one of a series of
Fujitsu computers released in Japan
With a pair of 6809 CPU's it was widely popular in Japan, and is one
of the few 6809 computers released.
In these tutorials we'll learn the about the FM7, and write some
simple programs for it
|
 |
 |
|
|
FM-7 |
Cpu |
Main: 2mhz 6809
Sub: 2mhz 6809 for GPU
|
Ram |
64k Ram
48k VRam |
Sound |
AY-3-8912
optional FM2203 add on |
Max Resolution |
640 x 200 @ 8 colors (RGB CMY BW) |
|
 |
ChibiAkumas FM7 Tutorials
Useful Documentation
FM-TechKnow (FM7
FM77)
FM7
New7 77 Assembly Introduction
Hello World Example
Here is a sample file...
We've provided a Header, containing the Length
and destination load address...
There is also an Exec address in the footer,
however this does not actually have any effect!
The hello world example uses the PrintChar
routine in the basic rom at $D08E of the FM-7 OS |
 |
StartUp File
To make our disk automatically start, we need a basic launcher.
Here we've written a BAS file, it will load machine code program
"PROG" (which has a built in destination address of &H2000)
Next we execute it with an EXEC command
We need to save this as "STARTUP" (Case Sensitive) |
 |
Building our program to the disk
We need to create a binary file (with a 2b0 extension)
We use ASW
to compile the program, and P2Bin to convert it to a binary.
To add a file to a disk we'll need the Ftools
kit
We'll use a template disk (with our STARTUP bas) and attach the 2b0
file to it |
 |
Sending Data to the Sub CPU
The Sub CPU handles graphics drawing and key input - it's a second
6809
To control it we have to send data to it via a 128 byte shared
memory block, between $FC80-FCFF ($D380-D3FF on the Sub CPU side)
To do this, we have to:
1. Wait for the Sub Cpu to not be busy (wait for Bit7 in $FD05 to
equal 0)
2. Halt the Sub Cpu (set Bit 7 of $FD05 to 1)
3. Copy command data to $FC80-FCFF
4. Resume the Sub CPU (write 0 to $FD05)
The command will then be processed by the sub CPU |
 |
if we HALT and RESUME the sub cpu but don't set a command there
WILL be trouble!
When we do this we need to set the 'request ready' bit (Bit 7 of
$F780) - this will stop the SUB CPU trying to process a command and
getting confused. |
 |
RAM Main CPU
From |
To |
Use |
$0000 |
$7FFF |
Ram |
$8000 |
$FBFF |
Basic Rom / Ram ** |
$FC00 |
$FC7F |
Ram |
$FC80 |
$FCFF |
Shared Ram (With SUB CPU $D380) |
$FD00 |
$FDFF |
IO area |
$FE00 |
$FEEF |
Boot Rom |
$FFF0 |
$FFFF |
Vectors |
** $FD0F Enable/Disable Basic ROM 8000-FC00 (Write=Disable... Read=
Enable)
RAM Sub CPU
From |
To |
Use |
$0000 |
$3FFF |
VRAM (BLUE) |
$4000 |
$7FFF |
VRAM (RED) |
$8000 |
$BFFF |
VRAM (GREEN) |
$C000 |
$CFFF |
Console Buffer Ram |
$D000 |
$D37F |
Work Ram |
$D380 |
$D3FF |
Shared Ram (With MAIN CPU $FC80) |
$D400 |
$D7FF |
IO area |
$D800 |
$DFFF |
Character Rom |
$E000 |
$FFFF |
CRT Monitor Rom |
Ports Main CPU
Address |
Read Bits |
Read Purpose |
Write Bits |
Write Purpose |
$FD00 |
D-------M |
Key Clock D8 |
Ss-------Ao |
Audio Casette / Printer |
$FD01 |
DDDDDDDD |
Key Data |
DDDDDDDD |
Printer Data |
$FD02 |
A-PPPPPP |
Audio Casette / Printer |
RRRR-TPK |
IRQ |
$FD03 |
----ETPK |
IRQ |
CK-----S |
Buzzer |
$FD04 |
------BA |
SubCpu Brk / Attention |
|
|
$FD05 |
B------E |
SubCPU Busy / Extdet |
HC-----Z |
Halt / Cancel / Z80 |
$FD06 |
DDDDDDDD |
RS232 Data |
DDDDDDDD |
RS232 Data |
$FD07 |
SSSSSSSS |
RS232 Status |
CCCCCCCC |
RS232 Comand |
$FD0D |
|
|
RRRRRRRR |
PSG AY Register (need to write zero after reg num?) |
$FD0E |
DDDDDDDD |
PSG AY Data |
DDDDDDDD |
PSG AY Data |
$FD0F |
BBBBBBBB |
ROM Bank |
BBBBBBBB |
Ram Bank |
$FD18 |
SSSSSSSS |
Floppy Status |
CCCCCCCC |
Floppy Command |
$FD19 |
DDDDDDDD |
Floppy Track Register |
DDDDDDDD |
Floppy Track Register |
$FD1A |
DDDDDDDD |
Floppy Sector Register |
DDDDDDDD |
Floppy Sector Register |
$FD1B |
DDDDDDDD |
Floppy Sector Register |
DDDDDDDD |
Floppy Sector Register |
$FD1C |
DDDDDDDD |
Floppy |
DDDDDDDD |
Floppy |
$FD1D |
DDDDDDDD |
Floppy |
DDDDDDDD |
Floppy |
$FD1E |
DDDDDDDD |
Floppy |
DDDDDDDD |
Floppy |
$FD1F |
DI------ |
Floppy |
|
Floppy |
$FD20 |
|
Kanji Rom 1 |
DDDDDDDD |
Kanji Rom 1 |
$FD21 |
|
Kanji Rom 1 |
DDDDDDDD |
Kanji Rom 1 |
$FD22 |
DDDDDDDD |
Kanji Rom 1 |
|
Kanji Rom 1 |
$FD23 |
DDDDDDDD |
Kanji Rom 1 |
|
Kanji Rom 1 |
$FD2C |
|
Kanji Rom 2 |
|
Kanji Rom 2 |
$FD2D |
|
Kanji Rom 2 |
|
Kanji Rom 2 |
$FD2E |
|
Kanji Rom 2 |
|
Kanji Rom 2 |
$FD2F |
|
Kanji Rom 2 |
|
Kanji Rom 2 |
$FD2E? |
|
Dictionary Bank |
|
Dictionary Bank |
$FD30 |
|
|
|
Analog Palette Number |
$FD31 |
|
|
|
Analog Palette Number |
$FD32 |
|
|
|
Analog Palette Blue Level |
$FD33 |
|
|
|
Analog Palette Red Level |
$FD34 |
|
|
|
Analog Palette Green Level |
$FD35 |
|
Speech Synthesis |
|
Speech Synthesis |
$FD37 |
|
|
-GRB-GRB |
Multipage (Display / Write Lock) |
$FD38 |
-----GRB |
Palette 0 (---) |
-----GRB |
Palette 0 |
$FD39 |
-----GRB |
Palette 1 (--B) |
-----GRB |
Palette 1 |
$FD3A |
-----GRB |
Palette 2 (-R-) |
-----GRB |
Palette 2 |
$FD3B |
-----GRB |
Palette 3 (-RB) |
-----GRB |
Palette 3 |
$FD3C |
-----GRB |
Palette 4 (G--) |
-----GRB |
Palette 4 |
$FD3D |
-----GRB |
Palette 5 (G-B) |
-----GRB |
Palette 5 |
$FD3E |
-----GRB |
Palette 6 (GR-) |
-----GRB |
Palette 6 |
$FD3F |
-----GRB |
Palette 7 (GRB) |
-----GRB |
Palette 7 |
$FD40 |
|
Modem Card |
|
Modem Card |
$FD41 |
|
Modem Card |
|
Modem Card |
$FD42 |
|
|
|
Modem Card |
$FD56 |
|
Voice Recognition Card |
|
Voice Recognition Card |
$FD57 |
|
Voice Recognition Card |
|
Voice Recognition Card |
$FD58 |
|
Handy Image Scanner |
|
|
$FD59 |
|
|
|
Handy Image Scanner |
$FD5A |
|
Handy Image Scanner |
|
|
$FD80 |
|
Memory Management Register |
|
Memory Management Register |
$FD81 |
|
Memory Management Register |
|
Memory Management Register |
$FD82 |
|
Memory Management Register |
|
Memory Management Register |
$FD83 |
|
Memory Management Register |
|
Memory Management Register |
$FD84 |
|
Memory Management Register |
|
Memory Management Register |
$FD85 |
|
Memory Management Register |
|
Memory Management Register |
$FD86 |
|
Memory Management Register |
|
Memory Management Register |
$FD87 |
|
Memory Management Register |
|
Memory Management Register |
$FD88 |
|
Memory Management Register |
|
Memory Management Register |
$FD89 |
|
Memory Management Register |
|
Memory Management Register |
$FD8A |
|
Memory Management Register |
|
Memory Management Register |
$FD8B |
|
Memory Management Register |
|
Memory Management Register |
$FD8C |
|
Memory Management Register |
|
Memory Management Register |
$FD8D |
|
Memory Management Register |
|
Memory Management Register |
$FD8E |
|
Memory Management Register |
|
Memory Management Register |
$FD8F |
|
Memory Management Register |
|
Memory Management Register |
$FD90 |
|
|
|
MMR Segment Register |
$FD92 |
|
|
|
Window Offset Register |
$FD93 |
|
|
|
Mode Select Register 1 |
$FD94 |
|
|
|
CPU Speed |
$FD95 |
|
Mode Select Switch 2 |
|
Mode Select Switch 2 |
$FD98 |
|
|
|
DMAC |
$FD99 |
|
DMAC |
|
DMAC |
$FDE0 |
|
|
|
Mouse |
$FDE1 |
|
Mouse |
|
Mouse |
$FDE2 |
|
Mouse |
|
Mouse |
$FDE3 |
|
Mouse |
|
Mouse |
$FDE4 |
|
Mouse |
|
Mouse |
$FDE5 |
|
Mouse |
|
Mouse |
$FDE6 |
|
Mouse |
|
Mouse |
$FDE7 |
|
Mouse |
|
Mouse |
$FDE8 |
|
Mouse |
|
Mouse |
$FDE9 |
|
|
|
MIDI |
$FDEA |
|
MIDI |
|
MIDI |
$FDEB |
|
MIDI |
|
MIDI |
$FDEC |
|
MIDI |
|
MIDI |
$FDED |
|
MIDI |
|
MIDI |
$FDEE |
|
MIDI |
|
MIDI |
$FDEF |
|
|
|
MIDI |
Ports Sub CPU
Address |
Read Bits |
Read Purpose |
Write Bits |
Write Purpose |
$D400 |
DDDDDDDD |
Key Data |
|
|
$D401 |
-------D |
Key Data |
|
|
$D402 |
|
Cancel IRQ ACK |
|
|
$D404 |
|
Main CPU Attention IRQ |
|
|
$D408 |
|
CRT ON |
|
CRT OFF |
$D409 |
|
Vram Access Set |
|
Vram Access Reset |
$D40A |
|
Ready |
|
Busy |
$D40D |
|
Ins LED ON |
|
Ins LED OFF |
$D40E |
|
|
--HHHHHH |
Vram Address H |
$D40F |
|
|
LLLLLLLL |
Vram Address L |
Colors
Char Map

Special Chars
Code |
|
Meaning |
$11 |
SF |
Start Field |
$12,X,Y |
SBA |
Set Buffer Address (Locate) |
$13,count,Ascii |
RC |
Repeat Character |
$05 |
EL |
Erase Line |
$07 |
BEL |
BELL (Beep) |
$08 |
BS |
BackSpace |
$09 |
HT |
Horizontal TAB |
$0A |
LF |
Line Feed |
$0B |
HOME |
Buffer Address to top of screen |
$0C |
EA |
Erase All (CLS) |
$0D |
CR |
Carrage Return |
$1C |
|
Right Cursor |
$1D |
|
Left Cursor |
$1E |
|
Up Cursor |
$1F |
|
Down Cursor |
$1B,$23 |
|
Lock Keyboard |
$1B,$22 |
|
Unlock Keyboard |
$1B,$39 |
|
Erase Key Buffer |
$1B,$67 |
|
Set Buffered Mode |
$1B,$69 |
|
Set Unbuffered Mode |
Graphics Operations
Code
|
Op |
Details |
0 |
PSET |
Set to Color |
1 |
PRESET |
Set to background Color |
2 |
OR |
Add to |
3 |
AND |
Mask |
4 |
XOR |
Invert |
5 |
NOT |
Flip bits |
Commands that can be sent to the Sub CPU
There are a variety of commands that can be sent to the Sub CPU, there
are some special 'secret' ones called the YAMAUCHI calls (Also know as
TEST commands),
These allow data to be direct copied to the SubCPU and allows for
execution
Gfx Cmd
|
Name
|
Purpose |
Data (Load into #$FC80) |
Returns |
$01 |
INIT |
Init Console |
DC.B unused,unused
DC.B $01,Background
DC.B Widh,Hei (80/40,25/20)
DC.B ScrollStart,ScrollEnd
DC.B SHowFunctions,ClearScreen,GreenScreen |
|
$02 |
ERASE |
Clear screen |
DC.B unused,unused
DC.B $02,Mode (0-3),Color |
|
$03 |
PUT |
Print Characters
|
dc.b unused,unused
dc.b continue (128=yes)
dc.b unused
dc.b $03
dc.b Bytecount
dc.b StringToSend
|
|
$04 |
GET |
|
|
|
$05 |
GETC |
|
|
|
$06 |
Get Character Block 1 |
|
|
|
$07 |
Put Character Block 1 |
|
|
|
$08 |
Get Character Block 2 |
|
|
|
$09 |
Put Character Block 2 |
|
|
|
$0A |
Get Buffer Address |
|
|
|
$0B |
Tab Set |
|
|
|
$0C |
Console Control |
|
|
|
$0D |
Erase 2 |
|
|
|
$15 |
Line |
Draw Lines, Fill Boxes
|
dc.b unused,unused
dc.b $15,color,operation
dc.w StartX,StartY,EndX,EndY
dc.b mode (line,square,filled) |
|
$16 |
Chain |
Draw a series of lines
|
|
|
$17 |
Point |
Draw Dots
|
dc.b unused,unused
dc.b $17,points (1-20)
(for each point)
dc.w Xpos,Ypos ;(X,Y)
dc.b Color,Operation
;Color,Operation
|
|
$18 |
Paint |
Fill an area
|
dc.b $18
dc.w Xpos,Ypos
dc.b FillColor
dc.b BoundaryCount
dc.b BoundaryColor....BoundaryColor
|
|
$19 |
Symbol |
Draw text with color, Scale and rotation
|
dc.b unused,unused
dc.b $19,Color,Operation
dc.b Rotation (0,90,180,270)
dc.b ScaleX,ScaleY (1=normal)
dc.w Xpos,Ypos
dc.b StringLen
dc.b "String"
|
|
$1A |
Change Color |
Swap colors for other colors
|
dc.b $1A
dc.w StartX,StartY,EndX,EndY
dc.b 2
;SwapCount
dc.b 7,6
;Old Color,New Color
dc.b 4,3
;Old Color,New Color
|
|
$1B |
Get Block 1 |
|
|
|
$1C |
Put Block 1 |
Send Monocrome data
|
|
|
$1D |
Get Block 2 |
|
|
|
$1E |
Put Block 2 |
Send Color Data
|
dc.b unused,Multiblock (128=Y)
dc.b $1E
dc.w StartX,StartY,EndX,EndY
dc.b Unused, Function, Bytes
dc.b pixel,pixel,pixel.... |
|
$1F |
Graphics Cursor |
|
|
|
$20 |
Character Line |
|
|
|
$29 |
Inkey |
|
DC.B unused,unused
DC.B $29,Option(Bit0=Wait,Bit1=Reset) |
DC.B ErrorCode,Unused,Unused
DC.B,Keycode (ASCII),Keyreturned? (1=yes) |
$2A |
Define String of PF |
|
|
|
$2B |
Get String of PF |
|
|
|
$2C |
Interrupt Control |
|
|
|
$3D |
Set Timer |
|
|
|
$3E |
Read Timer |
|
|
|
$3F - 90
|
YAMAUCHI END |
End command sequence |
DC.B unused,unused
DC.B $3F,�YAMAUCHI�,$90 |
|
$3F - 93
|
YAMAUCHI CALL |
Call program in sub cpu ram |
DC.B unused,unused
DC.B $3F,�YAMAUCHI�,$93
DC.W {address}
DC.B $90 |
|
$3F - 92
|
YAMAUCHI MOVE |
transfer data in sub cpu |
DC.B unused,unused
DC.B $3F,�YAMAUCHI�,$91
DC.W {FromAddrInSub}
DC.W {ToAddrInSub}
DC.W {LengthInBytes}
DC.B $90 |
|
$3F - 91 |
YAMAUCHI JUMP |
Jump to an address |
DC.B unused,unused
DC.B $3F,�YAMAUCHI�,$91
DC.W {address}
DC.B $90 |
|
$64 |
Continue |
Send more data (Put Block) |
dc.b unused,Multiblock (128=Y)
dc.b $64 ;Continue
dc.b pixel,pixel,pixel.... |
|
The FM8 required $3F to be followed with the 8 byte
'YAMAUCHI' string... but FM7 onwards didn't check it ...
There still needs to be 8 bytes 'there' before $9x commands - but
they can be anything.
|
 |
AY Registers
The procedure for setting and reading AY-3-8910
registers is not quite direct... the method is shown here |
Select Register:
RegNum -> $FD0E
#$03 -> $FD0D
#$00 -> $FD0D |
Write Selected Register:
New Value -> $FD0E
#$02 -> $FD0D
#$00 -> $FD0D |
Read Selected Register:
#$01 -> $FD0D
$FD0E -> Result
#$00 -> $FDOD |
FM Registers
The FM7 later gained a YM2203
FM card!
It's strangely backwards compatible with the AY too.
This had a built in joystick port we may want to use! |
Select Register:
RegNum -> $FD16
#$03 -> $FD15
#$00 -> $FD15 |
Write Selected Register:
New Value -> $FD16
#$02 -> $FD15
#$00 -> $FD15 |
Read Selected Register:
#$09 -> $FD15
$FD16 -> Result
#$00 -> $FD15 |
Joystick Reading
The original FM7 had no joystick... but the later FM card had one
as an upgrade.
The Joystick is connected to ports A (Reg14) & B (Reg15) Reg 14
selects which joystick to read (1 or 2)... reg 15 reads in from the
joystick. |
;Init Joystick
ldb #15 ;RegNum
lda #$7F
;Value (Turn off joysticks)
jsr FMRegWrite
ldb #7 ;RegNum
lda #%10111111 ;Value (Set
Direction B=Out R15 / A= In R14)
jsr FMRegWrite
ldb #15 ;$2F (Joy0) $5F (Joy1)
lda #$2F
jsr FMRegWrite
ldb #14
jsr FMRegRead
;A= %--21RLDU |
| |
Buy my Assembly programming book on Amazon in Print or Kindle!



Available worldwide! Search 'ChibiAkumas' on your local Amazon website!
Click here for more info!
Buy my Assembly programming book on Amazon in Print or Kindle!



Available worldwide! Search 'ChibiAkumas' on your local Amazon website!
Click here for more info!
|