|
![]() |
FM7 New7 77 Assembly Introduction
Hello World Example
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
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
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
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 |