1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2026-03-10 21:25:31 +00:00

Apple II DOS 3.3 binary ORIGIN

Example showing how to create a DOS 3.3 binary
header and program that is automatically loaded
into the desired ORIGIN memory address.
This commit is contained in:
Fred Sauer
2026-02-28 15:26:24 -08:00
parent 44f8b97ca5
commit 00e109ed67
2 changed files with 163 additions and 46 deletions

112
presets/apple2/dos33bin.a Normal file
View File

@@ -0,0 +1,112 @@
; --------------------------------------------------
; Example showing how to create a DOS 3.3 binary
; header and program that is automatically loaded
; into the desired ORIGIN memory address.
; --------------------------------------------------
processor 6502
; --------------------------------------------------
; Desired origin
; - Origin must be less than $C000
; - Origin + size must be less than $13000
; - Origin must be $0803 or aligned to $xx00
; --------------------------------------------------
ORIGIN equ $2000
SIZE equ END_OF_PRORGAM-ORIGIN
; --------------------------------------------------
; DOS 3.3 binary header (4 bytes)
; --------------------------------------------------
org ORIGIN - 4 ; Subtract 4 ensures correct memory locations
word ORIGIN ; Origin (2 bytes)
word SIZE ; Size (2 bytes), must be length - 4
; --------------------------------------------------
; ROM routines
; --------------------------------------------------
HOME equ $FC58
; --------------------------------------------------
; Origin and start of program
; --------------------------------------------------
org ORIGIN ; Starting address
start
; --------------------------------------------------
; Clear screen
; --------------------------------------------------
jsr HOME
; --------------------------------------------------
; Print "START $" (7 chars) to $0400..$0406
; --------------------------------------------------
ldx #0
pfx_loop
lda prefix,x
ora #$80
sta $0400,x
inx
cpx #7
bne pfx_loop
; --------------------------------------------------
; Print origin in hex to $0407 - $040A
; --------------------------------------------------
; High byte high nibble
lda #>start
lsr
lsr
lsr
lsr
tax
lda hexchar,x
ora #$80
sta $0407
; High byte low nibble
lda #>start
and #$0F
tax
lda hexchar,x
ora #$80
sta $0408
; Low byte high nibble
lda #<start
lsr
lsr
lsr
lsr
tax
lda hexchar,x
ora #$80
sta $0409
; Low byte low nibble
lda #<start
and #$0F
tax
lda hexchar,x
ora #$80
sta $040A
; --------------------------------------------------
; Endless loop (text stays on screen)
; --------------------------------------------------
done jmp done
; --------------------------------------------------
; Data
; --------------------------------------------------
prefix
byte "START $"
hexchar
byte "0123456789ABCDEF"
END_OF_PRORGAM ; Don't add instructions after this line

View File

@@ -6,52 +6,53 @@ import { Base6502MachinePlatform } from "../common/baseplatform";
import { CodeAnalyzer_apple2 } from "../common/analysis";
import { BaseMAME6502Platform } from "../common/mameplatform";
const APPLE2_PRESETS : Preset[] = [
{id:'sieve.c', name:'Sieve', category:"C"},
{id:'keyboardtest.c', name:'Keyboard Test'},
{id:'mandel.c', name:'Mandelbrot'},
{id:'tgidemo.c', name:'TGI Graphics Demo'},
{id:'Eliza.c', name:'Eliza'},
{id:'siegegame.c', name:'Siege Game'},
{id:'cosmic.c', name:'Cosmic Impalas'},
{id:'farmhouse.c', name:"Farmhouse Adventure"},
{id:'yum.c', name:"Yum Dice Game"},
{id:'lz4test.c', name:"LZ4 Decompressor"},
{id:'hgrtest.a', name:"HGR Test", category:"Assembly Language"},
{id:'conway.a', name:"Conway's Game of Life"},
{id:'lz4fh.a', name:"LZ4FH Decompressor"},
{id:'deltamod.dasm', name:"Delta Modulation Audio"},
// {id:'zap.dasm', name:"ZAP!"},
// {id:'tb_6502.s', name:'Tom Bombem (assembler game)'},
const APPLE2_PRESETS: Preset[] = [
{ id: 'sieve.c', name: 'Sieve', category: "C" },
{ id: 'keyboardtest.c', name: 'Keyboard Test' },
{ id: 'mandel.c', name: 'Mandelbrot' },
{ id: 'tgidemo.c', name: 'TGI Graphics Demo' },
{ id: 'Eliza.c', name: 'Eliza' },
{ id: 'siegegame.c', name: 'Siege Game' },
{ id: 'cosmic.c', name: 'Cosmic Impalas' },
{ id: 'farmhouse.c', name: "Farmhouse Adventure" },
{ id: 'yum.c', name: "Yum Dice Game" },
{ id: 'lz4test.c', name: "LZ4 Decompressor" },
{ id: 'hgrtest.a', name: "HGR Test", category: "Assembly Language" },
{ id: 'conway.a', name: "Conway's Game of Life" },
{ id: 'lz4fh.a', name: "LZ4FH Decompressor" },
{ id: 'deltamod.dasm', name: "Delta Modulation Audio" },
// {id:'zap.dasm', name:"ZAP!"},
// {id:'tb_6502.s', name:'Tom Bombem (assembler game)'},
{ id: 'dos33bin.a', name: "DOS 3.3 Binary" },
];
/// MAME support
class Apple2MAMEPlatform extends BaseMAME6502Platform implements Platform {
start () {
start() {
this.startModule(this.mainElement, {
jsfile:'mame8bitpc.js',
biosfile:['apple2e.zip'],
jsfile: 'mame8bitpc.js',
biosfile: ['apple2e.zip'],
//cfgfile:'nes.cfg',
driver:'apple2e',
width:280*2,
height:192*2,
driver: 'apple2e',
width: 280 * 2,
height: 192 * 2,
//romfn:'/emulator/cart.nes',
//romsize:romSize,
//romdata:new lzgmini().decode(lzgRom).slice(0, romSize),
preInit:function(_self) {
preInit: function (_self) {
},
});
}
getOpcodeMetadata = getOpcodeMetadata_6502;
getDefaultExtension () { return ".c"; };
getDefaultExtension() { return ".c"; };
getToolForFilename = getToolForFilename_6502;
getPresets () { return APPLE2_PRESETS; }
getPresets() { return APPLE2_PRESETS; }
loadROM (title, data) {
loadROM(title, data) {
this.loadROMFile(data);
// TODO
}
@@ -61,29 +62,33 @@ class Apple2MAMEPlatform extends BaseMAME6502Platform implements Platform {
class NewApple2Platform extends Base6502MachinePlatform<AppleII> implements Platform {
newMachine() { return new AppleII(); }
getPresets() { return APPLE2_PRESETS; }
newMachine() { return new AppleII(); }
getPresets() { return APPLE2_PRESETS; }
getDefaultExtension() { return ".c"; };
readAddress(a) { return this.machine.readConst(a); }
readAddress(a) { return this.machine.readConst(a); }
// TODO loadBIOS(bios) { this.machine.loadBIOS(a); }
getMemoryMap = function() { return { main:[
{name:'Zero Page RAM',start:0x0,size:0x100,type:'ram'},
{name:'Line Input RAM',start:0x200,size:0x100,type:'ram'},
{name:'RAM',start:0x300,size:0xc0,type:'ram'},
{name:'DOS Vectors',start:0x3c0,size:0x40,type:'ram'},
{name:'Text/Lores Page 1',start:0x400,size:0x400,type:'ram'},
{name:'RAM',start:0x800,size:0x1800,type:'ram'},
{name:'Hires Page 1',start:0x2000,size:0x2000,type:'ram'},
{name:'Hires Page 2',start:0x4000,size:0x2000,type:'ram'},
{name:'RAM',start:0x6000,size:0x6000,type:'ram'},
{name:'I/O',start:0xc000,size:0x1000,type:'io'},
{name:'ROM',start:0xd000,size:0x3000,type:'rom'},
] } };
getROMExtension(rom:Uint8Array) {
if (rom && rom.length == 35*16*256) return ".dsk"; // DSK image
getMemoryMap = function () {
return {
main: [
{ name: 'Zero Page RAM', start: 0x0, size: 0x100, type: 'ram' },
{ name: 'Line Input RAM', start: 0x200, size: 0x100, type: 'ram' },
{ name: 'RAM', start: 0x300, size: 0xc0, type: 'ram' },
{ name: 'DOS Vectors', start: 0x3c0, size: 0x40, type: 'ram' },
{ name: 'Text/Lores Page 1', start: 0x400, size: 0x400, type: 'ram' },
{ name: 'RAM', start: 0x800, size: 0x1800, type: 'ram' },
{ name: 'Hires Page 1', start: 0x2000, size: 0x2000, type: 'ram' },
{ name: 'Hires Page 2', start: 0x4000, size: 0x2000, type: 'ram' },
{ name: 'RAM', start: 0x6000, size: 0x6000, type: 'ram' },
{ name: 'I/O', start: 0xc000, size: 0x1000, type: 'io' },
{ name: 'ROM', start: 0xd000, size: 0x3000, type: 'rom' },
]
}
};
getROMExtension(rom: Uint8Array) {
if (rom && rom.length == 35 * 16 * 256) return ".dsk"; // DSK image
return ".bin";
};
getToolForFilename = (fn:string) : string => {
getToolForFilename = (fn: string): string => {
if (fn.endsWith(".lnk")) return "merlin32";
else return getToolForFilename_6502(fn);
}