Unify inc/ directories

This commit is contained in:
Joshua Bell 2019-10-03 21:23:00 -07:00
parent 78e1d2d2e6
commit 0626869e27
21 changed files with 26 additions and 1334 deletions

View File

@ -13,7 +13,7 @@ DEFINES = -D DD=$(DD) -D MM=$(MM) -D YY=$(YY)
.PHONY: clean all
all: $(TARGETS)
HEADERS = $(wildcard *.inc)
HEADERS = $(wildcard *.inc) $(wildcard ../inc/*.inc)
clean:
rm -f *.o

View File

@ -12,9 +12,9 @@
.include "apple2.inc"
.include "apple2.mac"
.include "inc/apple2.inc"
.include "inc/macros.inc"
.include "inc/prodos.inc"
.include "../inc/apple2.inc"
.include "../inc/macros.inc"
.include "../inc/prodos.inc"
;;; Miscellaneous

View File

@ -4,7 +4,7 @@ LDFLAGS = --config apple2-asm.cfg
OUTDIR = out
HEADERS = $(wildcard *.inc) $(wildcard inc/*.inc)
HEADERS = $(wildcard *.inc) $(wildcard ../inc/*.inc)
TARGETS = \
$(OUTDIR)/prodos.mod.BIN \

View File

@ -14,9 +14,9 @@
.include "apple2.mac"
.include "opcodes.inc"
.include "inc/apple2.inc"
.include "inc/macros.inc"
.include "inc/prodos.inc"
.include "../inc/apple2.inc"
.include "../inc/macros.inc"
.include "../inc/prodos.inc"
;;; ************************************************************
.include "driver_preamble.inc"

View File

@ -8,9 +8,9 @@
.include "apple2.inc"
.include "inc/apple2.inc"
.include "inc/macros.inc"
.include "inc/prodos.inc"
.include "../inc/apple2.inc"
.include "../inc/macros.inc"
.include "../inc/prodos.inc"
start:
MLI_CALL GET_TIME, 0

View File

@ -1,54 +0,0 @@
;;; ============================================================
;;;
;;; More Apple II Symbols
;;;
;;; ============================================================
;;; ============================================================
;;; Soft Switches
;;; ============================================================
RAMRDOFF := $C002
RAMRDON := $C003
RAMWRTOFF := $C004
RAMWRTON := $C005
ALTZPOFF := $C008
ALTZPON := $C009
CLR80VID := $C00C
SET80VID := $C00D
RDALTZP := $C016
RD80STORE := $C018
RDPAGE2 := $C01C
BANKSEL := $C073 ; Select RamWorks bank
ROMIN2 := $C082 ; Read ROM; no write
RWRAM1 := $C08B ; Read/write RAM bank 1
;;; ============================================================
;;; I/O Registers (for Slot 2)
;;; ============================================================
TDREG := $C088 + $20 ; ACIA Transmit Register (write)
RDREG := $C088 + $20 ; ACIA Receive Register (read)
STATUS := $C089 + $20 ; ACIA Status/Reset Register
COMMAND := $C08A + $20 ; ACIA Command Register (read/write)
CONTROL := $C08B + $20 ; ACIA Control Register (read/write)
;;; ============================================================
;;; Monitor ROM routines
;;; ============================================================
INIT := $FB2F
HOME := $FC58
GETLN := $FD6A ; with prompt character
GETLN2 := $FD6F ; no prompt character
CROUT := $FD8E
PRBYTE := $FDDA
COUT := $FDED
SETNORM := $FE84
SETKBD := $FE89
SETVID := $FE93
INPUT_BUFFER := $200

View File

@ -1,123 +0,0 @@
;;; ============================================================
;;; Generic Macros
;;; ============================================================
.define _is_immediate(arg) (.match (.mid (0, 1, {arg}), #))
.define _is_register(arg) (.match ({arg}, x) .or .match ({arg}, y))
.define _is_y_register(arg) (.match ({arg}, y))
.define _immediate_value(arg) (.right (.tcount ({arg})-1, {arg}))
.macro _op_lo op, arg
.if _is_immediate {arg}
op #<_immediate_value {arg}
.else
op arg
.endif
.endmacro
.macro _op_hi op, arg
.if _is_immediate {arg}
op #>_immediate_value {arg}
.else
op arg+1
.endif
.endmacro
;;; ============================================================
;;; Temporary org change, for relocated routines
__pushorg_depth__ .set 0
.macro pushorg addr
::__pushorg_depth__ .set ::__pushorg_depth__ + 1
.ident(.sprintf("__pushorg_saved__%d", ::__pushorg_depth__)) := *
.org addr
.ident(.sprintf("__pushorg_start__%d", ::__pushorg_depth__)) := *
.endmacro
.macro poporg
.org .ident(.sprintf("__pushorg_saved__%d", ::__pushorg_depth__)) + (* - .ident(.sprintf("__pushorg_start__%d", ::__pushorg_depth__)))
::__pushorg_depth__ .set ::__pushorg_depth__ - 1
.endmacro
;;; ============================================================
;;; Length-prefixed string
;;;
;;; Can include control chars by using:
;;;
;;; PASCAL_STRING {"abc",$0D,"def"}
.macro PASCAL_STRING str,res
.local data
.local end
.byte end - data
data: .byte str
end:
.if .paramcount > 1
.res res - (end - data), 0
.endif
.endmacro
;;; ============================================================
;;; Common patterns
.macro copy arg1, arg2, arg3, arg4
.if _is_register {arg2} && _is_register {arg4}
;; indexed load/indexed store
lda arg1,arg2
sta arg3,arg4
.elseif _is_register {arg2}
;; indexed load variant (arg2 is x or y)
lda arg1,arg2
sta arg3
.elseif _is_register {arg3}
;; indexed store variant (arg3 is x or y)
lda arg1
sta arg2,arg3
.else
lda arg1
sta arg2
.endif
.endmacro
;;; Copy 16-bit value
;;; copy16 #$1111, $2222 ; immediate, absolute
;;; copy16 $1111, $2222 ; absolute, absolute
;;; copy16 $1111,x, $2222 ; indirect load, absolute store
;;; copy16 $1111, $2222,x ; absolute load, indirect store
;;; copy16 $1111,x $2222,x ; indirect load, indirect store
;;; copy16 #$1111, $2222,x ; immediate load, indirect store
.macro copy16 arg1, arg2, arg3, arg4
.if _is_register {arg2} && _is_register {arg4}
;; indexed load/indexed store
lda arg1,arg2
sta arg3,arg4
lda arg1+1,arg2
sta arg3+1,arg4
.elseif _is_register {arg2}
;; indexed load variant (arg2 is x or y)
lda arg1,arg2
sta arg3
lda arg1+1,arg2
sta arg3+1
.elseif _is_register {arg3}
;; indexed store variant (arg3 is x or y)
_op_lo lda, {arg1}
sta arg2,arg3
_op_hi lda, {arg1}
sta arg2+1,arg3
.else
_op_lo lda, {arg1}
sta arg2
_op_hi lda, {arg1}
sta arg2+1
.endif
.endmacro
;;; ============================================================
;;; Set the high bit on the passed byte
.define HI(c) ((c)|$80)

View File

@ -1,477 +0,0 @@
;;; ============================================================
;;;
;;; ProDOS MLI
;;;
;;; ============================================================
;;; Entry point / Global Page
MLI := $BF00 ; Entry point
DATETIME := $BF06 ; JMP to clock routine
DEVADR := $BF10 ; Device driver addresses ($BF10-$BF2F)
NODEV := $BF10 ; "No Device Connected" entry (slot 0)
DEVNUM := $BF30 ; Most recent accessed device
DEVCNT := $BF31 ; Number of on-line devices minus 1
DEVLST := $BF32 ; Up to 14 units ($BF32-$BF3F)
BITMAP := $BF58 ; System memory bitmap
BITMAP_SIZE = $18 ; Bits for pages $00 to $BF
DATELO := $BF90 ; Date lo
DATEHI := $BF91 ; Date hi
TIMELO := $BF92 ; Time lo
TIMEHI := $BF93 ; Time hi
LEVEL := $BF94 ; File level
MACHID := $BF98 ; Machine ID
SLTBYT := $BF99 ; '1' bits indicate rom in slot (bit#)
IVERSION := $BFFD ; Interpreter Version
KVERSION := $BFFF ; ProDOS Kernel Version
;;; Patch Locations
SELECTOR := $D100
BLOCK_SIZE = $200
PATHNAME := $280
SYS_ADDR := $2000 ; Load address for SYS files
SYS_LEN = $BF00 - SYS_ADDR ; Maximum SYS file length
;;; ============================================================
;;; MLI Calls
;;; ============================================================
;;; Housekeeping Calls
CREATE = $C0
DESTROY = $C1
RENAME = $C2
SET_FILE_INFO = $C3
GET_FILE_INFO = $C4
ON_LINE = $C5
SET_PREFIX = $C6
GET_PREFIX = $C7
;;; Filing Calls
OPEN = $C8
NEWLINE = $C9
READ = $CA
WRITE = $CB
CLOSE = $CC
FLUSH = $CD
SET_MARK = $CE
GET_MARK = $CF
SET_EOF = $D0
GET_EOF = $D1
SET_BUF = $D2
GET_BUF = $D3
;;; System Calls
GET_TIME = $82
ALLOC_INTERRUPT = $40
DEALLOC_INTERRUPT = $41
QUIT = $65
;;; Direct Disk Access Commands
READ_BLOCK = $80
WRITE_BLOCK = $81
;;; ============================================================
;;; File Types
;;; ============================================================
FT_TYPELESS = $00
FT_BAD = $01
FT_TEXT = $04 ; ASCII Text File *
FT_BINARY = $06 ; Generic Binary File *
FT_GRAPHICS = $08 ; Graphics File
FT_DIRECTORY = $0F ; Directory *
FT_ADB = $19 ; AppleWorks Database *
FT_AWP = $1A ; AppleWorks Word Processing *
FT_ASP = $1B ; AppleWorks Spreadsheet *
FT_SRC = $B0 ; IIgs system type; re-used?
FT_S16 = $B3 ; IIgs Application Program
FT_PAS = $EF ; Pascal Area *
FT_CMD = $F0 ; ProDOS Command File *
FT_INT = $FA ; Integer BASIC Program *
FT_IVR = $FB ; Integer BASIC Variable File *
FT_BASIC = $FC ; Applesoft BASIC Program *
FT_VAR = $FD ; Applesoft BASIC Variable File *
FT_REL = $FE ; EDASM/Contiki Relocatable File *
FT_SYSTEM = $FF ; ProDOS System File *
;;; Types marked with * are known to BASIC.SYSTEM and have an
;;; associated three-letter abbreviation.
;;; ============================================================
;;; Access
;;; ============================================================
ACCESS_DEFAULT = %11000011
ACCESS_LOCKED = %00100001
;;; ============================================================
;;; Storage Types
;;; ============================================================
ST_STANDARD_FILE = $01
ST_LINKED_DIRECTORY = $0D
ST_VOLUME_DIRECTORY = $0F
;;; ============================================================
;;; Errors
;;; ============================================================
ERR_DEVICE_NOT_CONNECTED = $28
ERR_WRITE_PROTECTED = $2B
ERR_INVALID_PATHNAME = $40
ERR_INVALID_REFERENCE = $43
ERR_PATH_NOT_FOUND = $44
ERR_VOL_NOT_FOUND = $45
ERR_FILE_NOT_FOUND = $46
ERR_DUPLICATE_FILENAME= $47
ERR_OVERRUN_ERROR = $48
ERR_VOLUME_DIR_FULL = $49
ERR_END_OF_FILE = $4C
ERR_ACCESS_ERROR = $4E
ERR_DUPLICATE_VOLUME = $57
ERR_NETWORK_ERROR = $88
;;; ============================================================
;;; Directory Structures
;;; ============================================================
STORAGE_TYPE_MASK = $F0
NAME_LENGTH_MASK = $0F
;;; Volume Directory Header structure
.struct VolumeDirectoryHeader
prev_block .word
next_block .word
storage_type_name_length .byte
file_name .byte 15
reserved .byte 8
creation_date .word
creation_time .word
version .byte
min_version .byte
access .byte
entry_length .byte
entries_per_block .byte
file_count .word
;; same through here ---------
bit_map_pointer .word
total_blocks .word
.endstruct
.assert .sizeof(VolumeDirectoryHeader) = $2B, error, "incorrect struct size"
;;; Subdirectory Header structure
.struct SubdirectoryHeader
prev_block .word
next_block .word
storage_type_name_length .byte
file_name .byte 15
reserved .byte 8
creation_date .word
creation_time .word
version .byte
min_version .byte
access .byte
entry_length .byte
entries_per_block .byte
file_count .word
;; same through here ---------
parent_pointer .word
parent_entry_number .byte
parent_entry_length .byte
.endstruct
.assert .sizeof(SubdirectoryHeader) = $2B, error, "incorrect struct size"
;; File Entry structure
.struct FileEntry
storage_type_name_length .byte
file_name .byte 15
file_type .byte
key_pointer .word
blocks_used .word
eof .faraddr
creation_date .word
creation_time .word
version .byte
min_version .byte
access .byte
aux_type .word
mod_date .word
mod_time .word
header_pointer .word
.endstruct
.assert .sizeof(FileEntry) = $27, error, "incorrect struct size"
;;; ============================================================
;;; ProDOS Driver Protocol
;;; ============================================================
;;; Addresses for command parameters
DRIVER_COMMAND := $42
DRIVER_UNIT_NUMBER := $43
DRIVER_BUFFER := $44
DRIVER_BLOCK_NUMBER := $46
;;; Commands
DRIVER_COMMAND_STATUS = 0
DRIVER_COMMAND_READ = 1
DRIVER_COMMAND_WRITE = 2
DRIVER_COMMAND_FORMAT = 3
;;; ============================================================
;;; Macros
;;; ============================================================
.macro MLI_CALL op, addr
jsr MLI
.byte op
.addr addr
.endmacro
.macro DEFINE_OPEN_PARAMS name, pn, io, rn
.if .xmatch(.string(pn), "pathname")
;; If 'pathname' is passed then expansion yields a circular reference.
.error "Can't pass 'pathname' label to DEFINE_*_PARAMS"
.endif
.if .xmatch(.string(io), "io_buffer")
.error "Can't pass 'io_buffer' label to DEFINE_*_PARAMS"
.endif
.proc name
param_count: .byte 3
pathname: .addr pn
io_buffer: .addr io
.ifnblank rn
ref_num: .byte rn
.else
ref_num: .byte 0
.endif
.endproc
.endmacro
.macro DEFINE_READ_PARAMS name, db, rc
.proc name
param_count: .byte 4
ref_num: .byte 0
data_buffer: .addr db
request_count: .word rc
trans_count: .word 0
.endproc
.endmacro
.macro DEFINE_WRITE_PARAMS name, db, rc
.proc name
param_count: .byte 4
ref_num: .byte 0
data_buffer: .addr db
request_count: .word rc
trans_count: .word 0
.endproc
.endmacro
.macro DEFINE_CLOSE_PARAMS name
.proc name
param_count: .byte 1
ref_num: .byte 0
.endproc
.endmacro
.macro DEFINE_FLUSH_PARAMS name
.proc name
param_count: .byte 1
ref_num: .byte 0
.endproc
.endmacro
.macro DEFINE_GET_FILE_INFO_PARAMS name, pn
.if .xmatch(.string(pn), "pathname")
;; If 'pathname' is passed then expansion yields a circular reference.
.error "Can't pass 'pathname' label to DEFINE_*_PARAMS"
.endif
.proc name
param_count: .byte $A
pathname: .addr pn
access: .byte 0
file_type: .byte 0
aux_type: .word 0
storage_type: .byte 0
blocks_used: .word 0
mod_date: .word 0
mod_time: .word 0
create_date: .word 0
create_time: .word 0
.endproc
.endmacro
.macro DEFINE_SET_MARK_PARAMS name, pos
.proc name
param_count: .byte 2
ref_num: .byte 0
position: .faraddr pos
.endproc
.endmacro
.macro DEFINE_ON_LINE_PARAMS name, un, db
.proc name
param_count: .byte 2
.ifnblank un
unit_num: .byte un
.else
unit_num: .byte 0
.endif
data_buffer: .addr db
.endproc
.endmacro
.macro DEFINE_READ_BLOCK_PARAMS name, db, bn
.proc name
param_count: .byte 3
unit_num: .byte 0
data_buffer: .addr db
block_num: .word bn
.endproc
.endmacro
.macro DEFINE_WRITE_BLOCK_PARAMS name, db, bn
.proc name
param_count: .byte 3
unit_num: .byte 0
data_buffer: .addr db
block_num: .word bn
.endproc
.endmacro
.macro DEFINE_ALLOC_INTERRUPT_PARAMS name, ic
.proc alloc_interrupt_params
param_count: .byte 2
int_num: .byte 0
int_code: .addr ic
.endproc
.endmacro
.macro DEFINE_DEALLOC_INTERRUPT_PARAMS name
.proc dealloc_interrupt_params
param_count: .byte 1
int_num: .byte 0
.endproc
.endmacro
.macro DEFINE_QUIT_PARAMS name, ext, pathname
.proc name
param_count: .byte 4
.ifnblank ext
.byte ext
.else
.byte 0
.endif
.ifnblank pathname
.word pathname
.else
.word 0
.endif
.byte 0
.word 0
.endproc
.endmacro
.macro DEFINE_SET_PREFIX_PARAMS name, pn
.if .xmatch(.string(pn), "pathname")
;; If 'pathname' is passed then expansion yields a circular reference.
.error "Can't pass 'pathname' label to DEFINE_*_PARAMS"
.endif
.proc name
param_count: .byte 1
pathname: .addr pn
.endproc
.endmacro
.macro DEFINE_GET_PREFIX_PARAMS name, pn
.if .xmatch(.string(pn), "pathname")
;; If 'pathname' is passed then expansion yields a circular reference.
.error "Can't pass 'pathname' label to DEFINE_*_PARAMS"
.endif
.proc name
param_count: .byte 1
pathname: .addr pn
.endproc
.endmacro
.macro DEFINE_DESTROY_PARAMS name, pn
.if .xmatch(.string(pn), "pathname")
;; If 'pathname' is passed then expansion yields a circular reference.
.error "Can't pass 'pathname' label to DEFINE_*_PARAMS"
.endif
.proc name
param_count: .byte 1
pathname: .addr pn
.endproc
.endmacro
.macro DEFINE_CREATE_PARAMS name, pn, ac, ft, at, st
.if .xmatch(.string(pn), "pathname")
;; If 'pathname' is passed then expansion yields a circular reference.
.error "Can't pass 'pathname' label to DEFINE_*_PARAMS"
.endif
.proc name
param_count: .byte 7
pathname: .addr pn
.ifnblank ac
access: .byte ac
.else
access: .byte 0
.endif
.ifnblank ft
file_type: .byte ft
.else
file_type: .byte 0
.endif
.ifnblank at
aux_type: .word at
.else
aux_type: .word 0
.endif
.ifnblank st
storage_type: .byte st
.else
storage_type: .byte 0
.endif
create_date: .word 0
create_time: .word 0
.endproc
.endmacro
.macro DEFINE_SET_EOF_PARAMS name, eo
.proc name
param_count: .byte 2
ref_num: .byte 0
eof: .faraddr eo
.endproc
.endmacro
.macro DEFINE_GET_EOF_PARAMS name
.proc name
param_count: .byte 2
ref_num: .byte 0
eof: .faraddr 0
.endproc
.endmacro
.macro DEFINE_RENAME_PARAMS name, pn, np
.if .xmatch(.string(pn), "pathname")
;; If 'pathname' is passed then expansion yields a circular reference.
.error "Can't pass 'pathname' label to DEFINE_*_PARAMS"
.endif
.proc name
param_count: .byte 2
pathname: .addr pn
new_pathname: .addr np
.endproc
.endmacro

View File

@ -13,9 +13,9 @@
.include "apple2.mac"
.include "opcodes.inc"
.include "inc/apple2.inc"
.include "inc/macros.inc"
.include "inc/prodos.inc"
.include "../inc/apple2.inc"
.include "../inc/macros.inc"
.include "../inc/prodos.inc"
;;; ************************************************************
.include "driver_preamble.inc"

View File

@ -6,8 +6,8 @@
.include "apple2.inc"
.include "opcodes.inc"
.include "./inc/apple2.inc"
.include "./inc/prodos.inc"
.include "../inc/apple2.inc"
.include "../inc/prodos.inc"
.org $300

View File

@ -8,8 +8,8 @@
.include "apple2.inc"
.include "apple2.mac"
.include "inc/apple2.inc"
.include "inc/macros.inc"
.include "../inc/apple2.inc"
.include "../inc/macros.inc"
.org $2000

View File

@ -8,8 +8,8 @@
.include "apple2.inc"
.include "apple2.mac"
.include "inc/apple2.inc"
.include "inc/macros.inc"
.include "../inc/apple2.inc"
.include "../inc/macros.inc"
.org $2000

View File

@ -11,8 +11,8 @@
.include "apple2.mac"
.include "opcodes.inc"
.include "./inc/apple2.inc"
.include "./inc/macros.inc"
.include "../inc/apple2.inc"
.include "../inc/macros.inc"
.org $2000

View File

@ -4,7 +4,7 @@ LDFLAGS = --config apple2-asm.cfg
OUTDIR = out
HEADERS = $(wildcard *.inc) $(wildcard inc/*.inc)
HEADERS = $(wildcard *.inc) $(wildcard ../inc/*.inc)
TARGETS = $(OUTDIR)/ram.drv.system.SYS

View File

@ -1,54 +0,0 @@
;;; ============================================================
;;;
;;; More Apple II Symbols
;;;
;;; ============================================================
;;; ============================================================
;;; Soft Switches
;;; ============================================================
RAMRDOFF := $C002
RAMRDON := $C003
RAMWRTOFF := $C004
RAMWRTON := $C005
ALTZPOFF := $C008
ALTZPON := $C009
CLR80VID := $C00C
SET80VID := $C00D
RDALTZP := $C016
RD80STORE := $C018
RDPAGE2 := $C01C
BANKSEL := $C073 ; Select RamWorks bank
ROMIN2 := $C082 ; Read ROM; no write
RWRAM1 := $C08B ; Read/write RAM bank 1
;;; ============================================================
;;; I/O Registers (for Slot 2)
;;; ============================================================
TDREG := $C088 + $20 ; ACIA Transmit Register (write)
RDREG := $C088 + $20 ; ACIA Receive Register (read)
STATUS := $C089 + $20 ; ACIA Status/Reset Register
COMMAND := $C08A + $20 ; ACIA Command Register (read/write)
CONTROL := $C08B + $20 ; ACIA Control Register (read/write)
;;; ============================================================
;;; Monitor ROM routines
;;; ============================================================
INIT := $FB2F
HOME := $FC58
GETLN := $FD6A ; with prompt character
GETLN2 := $FD6F ; no prompt character
CROUT := $FD8E
PRBYTE := $FDDA
COUT := $FDED
SETNORM := $FE84
SETKBD := $FE89
SETVID := $FE93
INPUT_BUFFER := $200

View File

@ -1,123 +0,0 @@
;;; ============================================================
;;; Generic Macros
;;; ============================================================
.define _is_immediate(arg) (.match (.mid (0, 1, {arg}), #))
.define _is_register(arg) (.match ({arg}, x) .or .match ({arg}, y))
.define _is_y_register(arg) (.match ({arg}, y))
.define _immediate_value(arg) (.right (.tcount ({arg})-1, {arg}))
.macro _op_lo op, arg
.if _is_immediate {arg}
op #<_immediate_value {arg}
.else
op arg
.endif
.endmacro
.macro _op_hi op, arg
.if _is_immediate {arg}
op #>_immediate_value {arg}
.else
op arg+1
.endif
.endmacro
;;; ============================================================
;;; Temporary org change, for relocated routines
__pushorg_depth__ .set 0
.macro pushorg addr
::__pushorg_depth__ .set ::__pushorg_depth__ + 1
.ident(.sprintf("__pushorg_saved__%d", ::__pushorg_depth__)) := *
.org addr
.ident(.sprintf("__pushorg_start__%d", ::__pushorg_depth__)) := *
.endmacro
.macro poporg
.org .ident(.sprintf("__pushorg_saved__%d", ::__pushorg_depth__)) + (* - .ident(.sprintf("__pushorg_start__%d", ::__pushorg_depth__)))
::__pushorg_depth__ .set ::__pushorg_depth__ - 1
.endmacro
;;; ============================================================
;;; Length-prefixed string
;;;
;;; Can include control chars by using:
;;;
;;; PASCAL_STRING {"abc",$0D,"def"}
.macro PASCAL_STRING str,res
.local data
.local end
.byte end - data
data: .byte str
end:
.if .paramcount > 1
.res res - (end - data), 0
.endif
.endmacro
;;; ============================================================
;;; Common patterns
.macro copy arg1, arg2, arg3, arg4
.if _is_register {arg2} && _is_register {arg4}
;; indexed load/indexed store
lda arg1,arg2
sta arg3,arg4
.elseif _is_register {arg2}
;; indexed load variant (arg2 is x or y)
lda arg1,arg2
sta arg3
.elseif _is_register {arg3}
;; indexed store variant (arg3 is x or y)
lda arg1
sta arg2,arg3
.else
lda arg1
sta arg2
.endif
.endmacro
;;; Copy 16-bit value
;;; copy16 #$1111, $2222 ; immediate, absolute
;;; copy16 $1111, $2222 ; absolute, absolute
;;; copy16 $1111,x, $2222 ; indirect load, absolute store
;;; copy16 $1111, $2222,x ; absolute load, indirect store
;;; copy16 $1111,x $2222,x ; indirect load, indirect store
;;; copy16 #$1111, $2222,x ; immediate load, indirect store
.macro copy16 arg1, arg2, arg3, arg4
.if _is_register {arg2} && _is_register {arg4}
;; indexed load/indexed store
lda arg1,arg2
sta arg3,arg4
lda arg1+1,arg2
sta arg3+1,arg4
.elseif _is_register {arg2}
;; indexed load variant (arg2 is x or y)
lda arg1,arg2
sta arg3
lda arg1+1,arg2
sta arg3+1
.elseif _is_register {arg3}
;; indexed store variant (arg3 is x or y)
_op_lo lda, {arg1}
sta arg2,arg3
_op_hi lda, {arg1}
sta arg2+1,arg3
.else
_op_lo lda, {arg1}
sta arg2
_op_hi lda, {arg1}
sta arg2+1
.endif
.endmacro
;;; ============================================================
;;; Set the high bit on the passed byte
.define HI(c) ((c)|$80)

View File

@ -1,477 +0,0 @@
;;; ============================================================
;;;
;;; ProDOS MLI
;;;
;;; ============================================================
;;; Entry point / Global Page
MLI := $BF00 ; Entry point
DATETIME := $BF06 ; JMP to clock routine
DEVADR := $BF10 ; Device driver addresses ($BF10-$BF2F)
NODEV := $BF10 ; "No Device Connected" entry (slot 0)
DEVNUM := $BF30 ; Most recent accessed device
DEVCNT := $BF31 ; Number of on-line devices minus 1
DEVLST := $BF32 ; Up to 14 units ($BF32-$BF3F)
BITMAP := $BF58 ; System memory bitmap
BITMAP_SIZE = $18 ; Bits for pages $00 to $BF
DATELO := $BF90 ; Date lo
DATEHI := $BF91 ; Date hi
TIMELO := $BF92 ; Time lo
TIMEHI := $BF93 ; Time hi
LEVEL := $BF94 ; File level
MACHID := $BF98 ; Machine ID
SLTBYT := $BF99 ; '1' bits indicate rom in slot (bit#)
IVERSION := $BFFD ; Interpreter Version
KVERSION := $BFFF ; ProDOS Kernel Version
;;; Patch Locations
SELECTOR := $D100
BLOCK_SIZE = $200
PATHNAME := $280
SYS_ADDR := $2000 ; Load address for SYS files
SYS_LEN = $BF00 - SYS_ADDR ; Maximum SYS file length
;;; ============================================================
;;; MLI Calls
;;; ============================================================
;;; Housekeeping Calls
CREATE = $C0
DESTROY = $C1
RENAME = $C2
SET_FILE_INFO = $C3
GET_FILE_INFO = $C4
ON_LINE = $C5
SET_PREFIX = $C6
GET_PREFIX = $C7
;;; Filing Calls
OPEN = $C8
NEWLINE = $C9
READ = $CA
WRITE = $CB
CLOSE = $CC
FLUSH = $CD
SET_MARK = $CE
GET_MARK = $CF
SET_EOF = $D0
GET_EOF = $D1
SET_BUF = $D2
GET_BUF = $D3
;;; System Calls
GET_TIME = $82
ALLOC_INTERRUPT = $40
DEALLOC_INTERRUPT = $41
QUIT = $65
;;; Direct Disk Access Commands
READ_BLOCK = $80
WRITE_BLOCK = $81
;;; ============================================================
;;; File Types
;;; ============================================================
FT_TYPELESS = $00
FT_BAD = $01
FT_TEXT = $04 ; ASCII Text File *
FT_BINARY = $06 ; Generic Binary File *
FT_GRAPHICS = $08 ; Graphics File
FT_DIRECTORY = $0F ; Directory *
FT_ADB = $19 ; AppleWorks Database *
FT_AWP = $1A ; AppleWorks Word Processing *
FT_ASP = $1B ; AppleWorks Spreadsheet *
FT_SRC = $B0 ; IIgs system type; re-used?
FT_S16 = $B3 ; IIgs Application Program
FT_PAS = $EF ; Pascal Area *
FT_CMD = $F0 ; ProDOS Command File *
FT_INT = $FA ; Integer BASIC Program *
FT_IVR = $FB ; Integer BASIC Variable File *
FT_BASIC = $FC ; Applesoft BASIC Program *
FT_VAR = $FD ; Applesoft BASIC Variable File *
FT_REL = $FE ; EDASM/Contiki Relocatable File *
FT_SYSTEM = $FF ; ProDOS System File *
;;; Types marked with * are known to BASIC.SYSTEM and have an
;;; associated three-letter abbreviation.
;;; ============================================================
;;; Access
;;; ============================================================
ACCESS_DEFAULT = %11000011
ACCESS_LOCKED = %00100001
;;; ============================================================
;;; Storage Types
;;; ============================================================
ST_STANDARD_FILE = $01
ST_LINKED_DIRECTORY = $0D
ST_VOLUME_DIRECTORY = $0F
;;; ============================================================
;;; Errors
;;; ============================================================
ERR_DEVICE_NOT_CONNECTED = $28
ERR_WRITE_PROTECTED = $2B
ERR_INVALID_PATHNAME = $40
ERR_INVALID_REFERENCE = $43
ERR_PATH_NOT_FOUND = $44
ERR_VOL_NOT_FOUND = $45
ERR_FILE_NOT_FOUND = $46
ERR_DUPLICATE_FILENAME= $47
ERR_OVERRUN_ERROR = $48
ERR_VOLUME_DIR_FULL = $49
ERR_END_OF_FILE = $4C
ERR_ACCESS_ERROR = $4E
ERR_DUPLICATE_VOLUME = $57
ERR_NETWORK_ERROR = $88
;;; ============================================================
;;; Directory Structures
;;; ============================================================
STORAGE_TYPE_MASK = $F0
NAME_LENGTH_MASK = $0F
;;; Volume Directory Header structure
.struct VolumeDirectoryHeader
prev_block .word
next_block .word
storage_type_name_length .byte
file_name .byte 15
reserved .byte 8
creation_date .word
creation_time .word
version .byte
min_version .byte
access .byte
entry_length .byte
entries_per_block .byte
file_count .word
;; same through here ---------
bit_map_pointer .word
total_blocks .word
.endstruct
.assert .sizeof(VolumeDirectoryHeader) = $2B, error, "incorrect struct size"
;;; Subdirectory Header structure
.struct SubdirectoryHeader
prev_block .word
next_block .word
storage_type_name_length .byte
file_name .byte 15
reserved .byte 8
creation_date .word
creation_time .word
version .byte
min_version .byte
access .byte
entry_length .byte
entries_per_block .byte
file_count .word
;; same through here ---------
parent_pointer .word
parent_entry_number .byte
parent_entry_length .byte
.endstruct
.assert .sizeof(SubdirectoryHeader) = $2B, error, "incorrect struct size"
;; File Entry structure
.struct FileEntry
storage_type_name_length .byte
file_name .byte 15
file_type .byte
key_pointer .word
blocks_used .word
eof .faraddr
creation_date .word
creation_time .word
version .byte
min_version .byte
access .byte
aux_type .word
mod_date .word
mod_time .word
header_pointer .word
.endstruct
.assert .sizeof(FileEntry) = $27, error, "incorrect struct size"
;;; ============================================================
;;; ProDOS Driver Protocol
;;; ============================================================
;;; Addresses for command parameters
DRIVER_COMMAND := $42
DRIVER_UNIT_NUMBER := $43
DRIVER_BUFFER := $44
DRIVER_BLOCK_NUMBER := $46
;;; Commands
DRIVER_COMMAND_STATUS = 0
DRIVER_COMMAND_READ = 1
DRIVER_COMMAND_WRITE = 2
DRIVER_COMMAND_FORMAT = 3
;;; ============================================================
;;; Macros
;;; ============================================================
.macro MLI_CALL op, addr
jsr MLI
.byte op
.addr addr
.endmacro
.macro DEFINE_OPEN_PARAMS name, pn, io, rn
.if .xmatch(.string(pn), "pathname")
;; If 'pathname' is passed then expansion yields a circular reference.
.error "Can't pass 'pathname' label to DEFINE_*_PARAMS"
.endif
.if .xmatch(.string(io), "io_buffer")
.error "Can't pass 'io_buffer' label to DEFINE_*_PARAMS"
.endif
.proc name
param_count: .byte 3
pathname: .addr pn
io_buffer: .addr io
.ifnblank rn
ref_num: .byte rn
.else
ref_num: .byte 0
.endif
.endproc
.endmacro
.macro DEFINE_READ_PARAMS name, db, rc
.proc name
param_count: .byte 4
ref_num: .byte 0
data_buffer: .addr db
request_count: .word rc
trans_count: .word 0
.endproc
.endmacro
.macro DEFINE_WRITE_PARAMS name, db, rc
.proc name
param_count: .byte 4
ref_num: .byte 0
data_buffer: .addr db
request_count: .word rc
trans_count: .word 0
.endproc
.endmacro
.macro DEFINE_CLOSE_PARAMS name
.proc name
param_count: .byte 1
ref_num: .byte 0
.endproc
.endmacro
.macro DEFINE_FLUSH_PARAMS name
.proc name
param_count: .byte 1
ref_num: .byte 0
.endproc
.endmacro
.macro DEFINE_GET_FILE_INFO_PARAMS name, pn
.if .xmatch(.string(pn), "pathname")
;; If 'pathname' is passed then expansion yields a circular reference.
.error "Can't pass 'pathname' label to DEFINE_*_PARAMS"
.endif
.proc name
param_count: .byte $A
pathname: .addr pn
access: .byte 0
file_type: .byte 0
aux_type: .word 0
storage_type: .byte 0
blocks_used: .word 0
mod_date: .word 0
mod_time: .word 0
create_date: .word 0
create_time: .word 0
.endproc
.endmacro
.macro DEFINE_SET_MARK_PARAMS name, pos
.proc name
param_count: .byte 2
ref_num: .byte 0
position: .faraddr pos
.endproc
.endmacro
.macro DEFINE_ON_LINE_PARAMS name, un, db
.proc name
param_count: .byte 2
.ifnblank un
unit_num: .byte un
.else
unit_num: .byte 0
.endif
data_buffer: .addr db
.endproc
.endmacro
.macro DEFINE_READ_BLOCK_PARAMS name, db, bn
.proc name
param_count: .byte 3
unit_num: .byte 0
data_buffer: .addr db
block_num: .word bn
.endproc
.endmacro
.macro DEFINE_WRITE_BLOCK_PARAMS name, db, bn
.proc name
param_count: .byte 3
unit_num: .byte 0
data_buffer: .addr db
block_num: .word bn
.endproc
.endmacro
.macro DEFINE_ALLOC_INTERRUPT_PARAMS name, ic
.proc alloc_interrupt_params
param_count: .byte 2
int_num: .byte 0
int_code: .addr ic
.endproc
.endmacro
.macro DEFINE_DEALLOC_INTERRUPT_PARAMS name
.proc dealloc_interrupt_params
param_count: .byte 1
int_num: .byte 0
.endproc
.endmacro
.macro DEFINE_QUIT_PARAMS name, ext, pathname
.proc name
param_count: .byte 4
.ifnblank ext
.byte ext
.else
.byte 0
.endif
.ifnblank pathname
.word pathname
.else
.word 0
.endif
.byte 0
.word 0
.endproc
.endmacro
.macro DEFINE_SET_PREFIX_PARAMS name, pn
.if .xmatch(.string(pn), "pathname")
;; If 'pathname' is passed then expansion yields a circular reference.
.error "Can't pass 'pathname' label to DEFINE_*_PARAMS"
.endif
.proc name
param_count: .byte 1
pathname: .addr pn
.endproc
.endmacro
.macro DEFINE_GET_PREFIX_PARAMS name, pn
.if .xmatch(.string(pn), "pathname")
;; If 'pathname' is passed then expansion yields a circular reference.
.error "Can't pass 'pathname' label to DEFINE_*_PARAMS"
.endif
.proc name
param_count: .byte 1
pathname: .addr pn
.endproc
.endmacro
.macro DEFINE_DESTROY_PARAMS name, pn
.if .xmatch(.string(pn), "pathname")
;; If 'pathname' is passed then expansion yields a circular reference.
.error "Can't pass 'pathname' label to DEFINE_*_PARAMS"
.endif
.proc name
param_count: .byte 1
pathname: .addr pn
.endproc
.endmacro
.macro DEFINE_CREATE_PARAMS name, pn, ac, ft, at, st
.if .xmatch(.string(pn), "pathname")
;; If 'pathname' is passed then expansion yields a circular reference.
.error "Can't pass 'pathname' label to DEFINE_*_PARAMS"
.endif
.proc name
param_count: .byte 7
pathname: .addr pn
.ifnblank ac
access: .byte ac
.else
access: .byte 0
.endif
.ifnblank ft
file_type: .byte ft
.else
file_type: .byte 0
.endif
.ifnblank at
aux_type: .word at
.else
aux_type: .word 0
.endif
.ifnblank st
storage_type: .byte st
.else
storage_type: .byte 0
.endif
create_date: .word 0
create_time: .word 0
.endproc
.endmacro
.macro DEFINE_SET_EOF_PARAMS name, eo
.proc name
param_count: .byte 2
ref_num: .byte 0
eof: .faraddr eo
.endproc
.endmacro
.macro DEFINE_GET_EOF_PARAMS name
.proc name
param_count: .byte 2
ref_num: .byte 0
eof: .faraddr 0
.endproc
.endmacro
.macro DEFINE_RENAME_PARAMS name, pn, np
.if .xmatch(.string(pn), "pathname")
;; If 'pathname' is passed then expansion yields a circular reference.
.error "Can't pass 'pathname' label to DEFINE_*_PARAMS"
.endif
.proc name
param_count: .byte 2
pathname: .addr pn
new_pathname: .addr np
.endproc
.endmacro

View File

@ -13,9 +13,9 @@
.include "apple2.mac"
.include "opcodes.inc"
.include "inc/apple2.inc"
.include "inc/macros.inc"
.include "inc/prodos.inc"
.include "../inc/apple2.inc"
.include "../inc/macros.inc"
.include "../inc/prodos.inc"
;;; ************************************************************
.include "driver_preamble.inc"