diff --git a/common.inc b/common.inc deleted file mode 100644 index 682b8ea..0000000 --- a/common.inc +++ /dev/null @@ -1,125 +0,0 @@ -;;; ------------------------------------------------------------ -;;; ASCII - -BELL := $07 -BS := $08 -CR := $0D - -;;; ------------------------------------------------------------ -;;; Constants - -MAX_DW := $FFFF - - -;;; ------------------------------------------------------------ -;;; Softswitches - -CLR80VID := $C00C ; 40 Columns -ROMIN2 := $C082 ; Read ROM; no write -RWRAM1 := $C08B ; Read/write RAM bank 1 - -;;; ------------------------------------------------------------ -;;; ProDOS - -PRODOS := $BF00 -DATETIME := $BF06 -DEVNUM := $BF30 -BITMAP := $BF58 -BITMAP_SIZE := 24 ; 24 bytes in system bit map -DATELO := $BF90 -TIMELO := $BF92 -MACHID := $BF98 - -SYS_ADDR := $2000 ; Load address for SYSTEM files -PATHNAME := $0280 ; Pathname of loaded system file - -;;; MLI commands -MLI_QUIT := $65 -MLI_READ_BLOCK := $80 -MLI_GET_TIME := $82 -MLI_OPEN := $C8 -MLI_READ := $CA -MLI_CLOSE := $CC - -.macro PRODOS_CALL call, params - jsr PRODOS - .byte call - .addr params -.endmacro - -;;; Volume Directory Block Header structure -.scope VolumeDirectoryBlockHeader - prev_block := $00 - next_block := $02 - entry_length := $23 - entries_per_block := $24 - header_length := $2B -.endscope - -;; File Entry structure -.scope FileEntry - storage_type := $00 - name_length := $00 - file_name := $01 - file_type := $10 -.endscope - -;;; ------------------------------------------------------------ -;;; Monitor - -INIT := $FB2F -MON_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 - -;;; ------------------------------------------------------------ -;;; 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) - -;;; ------------------------------------------------------------ - -;;; Length-prefixed string -.macro PASCAL_STRING arg - .byte .strlen(arg) - .byte arg -.endmacro - -;;; ------------------------------------------------------------ - -;;; Define a string with high bits set -;;; e.g. HIASCII "Ding ding", $7, $7 -.macro HIASCII arg, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 - .if .blank(arg) - .exitmacro - .endif - .if .match ({arg}, "") ; string? - .repeat .strlen(arg), i - .byte .strat(arg, i) | $80 - .endrep - .else ; otherwise assume number/char/identifier - .byte (arg | $80) - .endif - HIASCII arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 -.endmacro - -;;; Like HIASCII, but null-terminated -.macro HIASCIIZ arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 - HIASCII arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 - .byte 0 -.endmacro - -;;; Set the high bit on the passed byte -.define HI(c) ((c)|$80) diff --git a/cricket.system.s b/cricket.system.s index e89164f..c074267 100644 --- a/cricket.system.s +++ b/cricket.system.s @@ -12,7 +12,9 @@ .include "apple2.inc" .include "opcodes.inc" - .include "./common.inc" + .include "inc/apple2.inc" + .include "inc/macros.inc" + .include "inc/prodos.inc" ;;; ------------------------------------------------------------ @@ -78,14 +80,14 @@ load: lda src,y ; self-modified beq pre_install floop: inc $A8 dex - beq copy + beq @copy lda PATHNAME,x eor #'/' asl a bne floop ;; Copy name into |self_name| buffer -copy: ldy #0 +@copy: ldy #0 cloop: iny inx lda PATHNAME,x @@ -224,7 +226,7 @@ cricket_not_found: not_found: ;; Show failure message - jsr MON_HOME + jsr HOME jsr zstrout HIASCIIZ CR, CR, CR, PRODUCT, " - Not Found." jmp launch_next_sys_file @@ -312,7 +314,7 @@ loop: lda driver,y ;; Display success message bit ROMIN2 - jsr MON_HOME + jsr HOME jsr zstrout HIASCIIZ CR, CR, CR, PRODUCT, " - Installed " @@ -364,16 +366,16 @@ loop: lda driver,y sta read_block_params_unit_num jsr read_block - lda data_buffer + VolumeDirectoryBlockHeader::entry_length + lda data_buffer + VolumeDirectoryHeader::entry_length sta entry_length_mod - lda data_buffer + VolumeDirectoryBlockHeader::entries_per_block + lda data_buffer + VolumeDirectoryHeader::entries_per_block sta entries_per_block_mod lda #1 sta num - lda #<(data_buffer + VolumeDirectoryBlockHeader::header_length) + lda #<(data_buffer + .sizeof(VolumeDirectoryHeader)) sta ptr - lda #>(data_buffer + VolumeDirectoryBlockHeader::header_length) + lda #>(data_buffer + .sizeof(VolumeDirectoryHeader)) sta ptr+1 ;; Process directory entry @@ -381,7 +383,7 @@ entry: ldy #FileEntry::file_type ; file_type lda (ptr),y cmp #$FF ; type=SYS bne next - ldy #FileEntry::storage_type + ldy #FileEntry::storage_type_name_length lda (ptr),y and #$30 ; regular file (not directory, pascal) beq next @@ -425,9 +427,9 @@ next: lda ptr entries_per_block_mod := *-1 bcc entry - lda data_buffer + VolumeDirectoryBlockHeader::next_block + lda data_buffer + VolumeDirectoryHeader::next_block sta read_block_params_block_num - lda data_buffer + VolumeDirectoryBlockHeader::next_block + 1 + lda data_buffer + VolumeDirectoryHeader::next_block + 1 sta read_block_params_block_num+1 ora read_block_params_block_num beq not_found ; last block has next=0 @@ -544,7 +546,7 @@ lowercase_mask: ;;; Invoke ProDOS QUIT routine. .proc quit - PRODOS_CALL MLI_QUIT, quit_params + MLI_CALL QUIT, quit_params .byte 0 ; crash if QUIT fails rts .proc quit_params @@ -560,7 +562,7 @@ lowercase_mask: ;;; Read a disk block. .proc read_block - PRODOS_CALL MLI_READ_BLOCK, read_block_params + MLI_CALL READ_BLOCK, read_block_params bcs on_error rts .endproc @@ -578,16 +580,16 @@ block_num: .word 2 ; block_num - block 2 is volume directory ;;; Load/execute the system file in PATHNAME .proc invoke_system_file - PRODOS_CALL MLI_OPEN, open_params + MLI_CALL OPEN, open_params bcs on_error lda open_params_ref_num sta read_params_ref_num - PRODOS_CALL MLI_READ, read_params + MLI_CALL READ, read_params bcs on_error - PRODOS_CALL MLI_CLOSE, close_params + MLI_CALL CLOSE, close_params bcs on_error jmp SYS_ADDR ; Invoke loaded SYSTEM file diff --git a/date.s b/date.s index db0f1e1..e048633 100644 --- a/date.s +++ b/date.s @@ -7,10 +7,13 @@ .org $2000 .include "apple2.inc" - .include "common.inc" + + .include "inc/apple2.inc" + .include "inc/macros.inc" + .include "inc/prodos.inc" start: - PRODOS_CALL MLI_GET_TIME, 0 + MLI_CALL GET_TIME, 0 ;;; Standard format: ;;; diff --git a/inc/apple2.inc b/inc/apple2.inc new file mode 100644 index 0000000..a46fe5c --- /dev/null +++ b/inc/apple2.inc @@ -0,0 +1,68 @@ +;;; ============================================================ +;;; +;;; More Apple II Symbols +;;; +;;; ============================================================ + +;;; ============================================================ +;;; ASCII +;;; ============================================================ + +BELL := $07 +BS := $08 +CR := $0D + +;;; ============================================================ +;;; Constants +;;; ============================================================ + +MAX_DW := $FFFF + +;;; ============================================================ +;;; 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 diff --git a/inc/macros.inc b/inc/macros.inc new file mode 100644 index 0000000..a1f475d --- /dev/null +++ b/inc/macros.inc @@ -0,0 +1,145 @@ +;;; ============================================================ +;;; 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 + +;;; ============================================================ + +;;; Define a string with high bits set +;;; e.g. HIASCII "Ding ding", $7, $7 +.macro HIASCII arg, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 + .if .blank(arg) + .exitmacro + .endif + .if .match ({arg}, "") ; string? + .repeat .strlen(arg), i + .byte .strat(arg, i) | $80 + .endrep + .else ; otherwise assume number/char/identifier + .byte (arg | $80) + .endif + HIASCII arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 +.endmacro + +;;; Like HIASCII, but null-terminated +.macro HIASCIIZ arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 + HIASCII arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 + .byte 0 +.endmacro + +;;; Set the high bit on the passed byte +.define HI(c) ((c)|$80) diff --git a/inc/prodos.inc b/inc/prodos.inc new file mode 100644 index 0000000..637e44e --- /dev/null +++ b/inc/prodos.inc @@ -0,0 +1,477 @@ +;;; ============================================================ +;;; +;;; 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 diff --git a/ns.clock.system.s b/ns.clock.system.s index 09c8dc4..bbe9b22 100644 --- a/ns.clock.system.s +++ b/ns.clock.system.s @@ -11,8 +11,9 @@ .include "apple2.inc" .include "opcodes.inc" - .include "./common.inc" - + .include "inc/apple2.inc" + .include "inc/macros.inc" + .include "inc/prodos.inc" ;;; ------------------------------------------------------------ @@ -76,14 +77,14 @@ load: lda src,y ; self-modified beq pre_install floop: inc $A8 dex - beq copy + beq @copy lda PATHNAME,x eor #'/' asl a bne floop ;; Copy name into |self_name| buffer -copy: ldy #0 +@copy: ldy #0 cloop: iny inx lda PATHNAME,x @@ -237,7 +238,7 @@ not_found: bpl :- ;; Show failure message - jsr MON_HOME + jsr HOME jsr zstrout HIASCIIZ CR, CR, CR, PRODUCT, " - Not Found." jmp launch_next_sys_file @@ -286,7 +287,7 @@ loop: lda driver,y ;; Display success message bit ROMIN2 - jsr MON_HOME + jsr HOME jsr zstrout HIASCIIZ CR, CR, CR, PRODUCT, " - Installed " @@ -338,16 +339,16 @@ loop: lda driver,y sta read_block_params_unit_num jsr read_block - lda data_buffer + VolumeDirectoryBlockHeader::entry_length + lda data_buffer + VolumeDirectoryHeader::entry_length sta entry_length_mod - lda data_buffer + VolumeDirectoryBlockHeader::entries_per_block + lda data_buffer + VolumeDirectoryHeader::entries_per_block sta entries_per_block_mod lda #1 sta num - lda #<(data_buffer + VolumeDirectoryBlockHeader::header_length) + lda #<(data_buffer + .sizeof(VolumeDirectoryHeader)) sta ptr - lda #>(data_buffer + VolumeDirectoryBlockHeader::header_length) + lda #>(data_buffer + .sizeof(VolumeDirectoryHeader)) sta ptr+1 ;; Process directory entry @@ -355,7 +356,7 @@ entry: ldy #FileEntry::file_type ; file_type lda (ptr),y cmp #$FF ; type=SYS bne next - ldy #FileEntry::storage_type + ldy #FileEntry::storage_type_name_length lda (ptr),y and #$30 ; regular file (not directory, pascal) beq next @@ -399,9 +400,9 @@ next: lda ptr entries_per_block_mod := *-1 bcc entry - lda data_buffer + VolumeDirectoryBlockHeader::next_block + lda data_buffer + VolumeDirectoryHeader::next_block sta read_block_params_block_num - lda data_buffer + VolumeDirectoryBlockHeader::next_block + 1 + lda data_buffer + VolumeDirectoryHeader::next_block + 1 sta read_block_params_block_num+1 ora read_block_params_block_num beq not_found ; last block has next=0 @@ -518,7 +519,7 @@ lowercase_mask: ;;; Invoke ProDOS QUIT routine. .proc quit - PRODOS_CALL MLI_QUIT, quit_params + MLI_CALL QUIT, quit_params .byte 0 ; crash if QUIT fails rts .proc quit_params @@ -534,7 +535,7 @@ lowercase_mask: ;;; Read a disk block. .proc read_block - PRODOS_CALL MLI_READ_BLOCK, read_block_params + MLI_CALL READ_BLOCK, read_block_params bcs on_error rts .endproc @@ -552,16 +553,16 @@ block_num: .word 2 ; block_num - block 2 is volume directory ;;; Load/execute the system file in PATHNAME .proc invoke_system_file - PRODOS_CALL MLI_OPEN, open_params + MLI_CALL OPEN, open_params bcs on_error lda open_params_ref_num sta read_params_ref_num - PRODOS_CALL MLI_READ, read_params + MLI_CALL READ, read_params bcs on_error - PRODOS_CALL MLI_CLOSE, close_params + MLI_CALL CLOSE, close_params bcs on_error jmp SYS_ADDR ; Invoke loaded SYSTEM file diff --git a/prodos.mod.s b/prodos.mod.s index 28f8374..dbf4e4a 100644 --- a/prodos.mod.s +++ b/prodos.mod.s @@ -6,7 +6,8 @@ .include "apple2.inc" .include "opcodes.inc" - .include "./common.inc" + .include "./inc/apple2.inc" + .include "./inc/prodos.inc" .org $300 diff --git a/set.date.s b/set.date.s index 29f7717..d9b6e80 100644 --- a/set.date.s +++ b/set.date.s @@ -5,7 +5,9 @@ .linecont + .include "apple2.inc" - .include "./common.inc" + + .include "inc/apple2.inc" + .include "inc/macros.inc" .org $2000 diff --git a/set.time.s b/set.time.s index f77c4b8..12b266f 100644 --- a/set.time.s +++ b/set.time.s @@ -5,7 +5,9 @@ .linecont + .include "apple2.inc" - .include "./common.inc" + + .include "inc/apple2.inc" + .include "inc/macros.inc" .org $2000 diff --git a/test.s b/test.s index 61f7c9b..5f78967 100644 --- a/test.s +++ b/test.s @@ -9,7 +9,8 @@ .include "apple2.inc" .include "opcodes.inc" - .include "./common.inc" + .include "./inc/apple2.inc" + .include "./inc/macros.inc" .org $2000