mirror of
https://github.com/david-schmidt/Davex.git
synced 2024-06-10 18:29:29 +00:00
451 lines
9.4 KiB
NASM
451 lines
9.4 KiB
NASM
|
|
.include "Common/2/Globals2.asm"
|
|
.include "Common/2/Apple.Globals2.asm"
|
|
.include "Common/2/Mli.globals2.asm"
|
|
.include "Common/Macros.asm"
|
|
|
|
CSTACK = $B000 ; AF00..AFFF
|
|
|
|
.segment "STARTUP"
|
|
_XC_STARTUP:
|
|
.export _XC_STARTUP
|
|
.import _main
|
|
.importzp sp
|
|
.importzp sreg
|
|
.import popa
|
|
|
|
lda #>CSTACK
|
|
ldx #<CSTACK
|
|
sta sp+1
|
|
stx sp
|
|
; [TODO] Call constructors/inits, and initialize any static data
|
|
jmp _main
|
|
|
|
; Override the library COUT, which would enable language-card memory afterwards. This is called by puts(), for example.
|
|
.export COUT
|
|
COUT = $fded
|
|
|
|
; export COUT() for direct use from C: Prints character in inverse if bit 7 is clear.
|
|
.export _COUT
|
|
_COUT = cout
|
|
|
|
.export _CROUT
|
|
_CROUT = crout
|
|
|
|
.export _PRBYTE
|
|
_PRBYTE = prbyte
|
|
|
|
.export _SETNORM
|
|
_SETNORM = normal
|
|
|
|
.export _SETINV
|
|
_SETINV = inverse
|
|
|
|
|
|
.macro returnTrueForCLC
|
|
ldx #0
|
|
txa
|
|
rol a
|
|
eor #1
|
|
rts
|
|
.endmacro
|
|
|
|
; __fastcall__ calling convention: last parameter is in sreg+1/sreg/X/A
|
|
; return value in XA, or sreg+1/sreg/X/A
|
|
|
|
; extern _Bool __fastcall__ xgetparm_ch_nil(uint8_t optionCharacter);
|
|
.export _xgetparm_ch_nil
|
|
_xgetparm_ch_nil:
|
|
jsr xgetparm_ch
|
|
returnTrueForCLC
|
|
|
|
; extern _Bool __fastcall__ xgetparm_ch_int1(uint8_t optionCharacter, uint8_t* outValue); // int1
|
|
.export _xgetparm_ch_int1
|
|
_xgetparm_ch_int1:
|
|
stx p+1
|
|
sta p
|
|
jsr popa ; option character [TODO] pop just 1 byte, or 2?
|
|
jsr xgetparm_ch ; 1-byte result in Y
|
|
bcs :+
|
|
tya
|
|
ldy #0
|
|
sta (p),y
|
|
: returnTrueForCLC
|
|
|
|
; extern _Bool __fastcall__ xgetparm_ch_int2(uint8_t optionCharacter, uint16_t* outValue);
|
|
.export _xgetparm_ch_int2
|
|
_xgetparm_ch_int2:
|
|
stx num+1
|
|
sta num
|
|
jsr popa ; option character [TODO] pop just 1 byte, or 2?
|
|
jsr xgetparm_ch ; 2-byte result in XY
|
|
getparm_return_int2:
|
|
bcs :+
|
|
; Result is in XY, and we need to store it at (num) as 2 bytes
|
|
tya
|
|
ldy #0
|
|
sta (num),y
|
|
txa
|
|
iny
|
|
sta (num),y
|
|
: returnTrueForCLC
|
|
|
|
|
|
; extern _Bool __fastcall__ xgetparm_ch_int3(uint8_t optionCharacter, uint32_t* outValue);
|
|
.export _xgetparm_ch_int3
|
|
_xgetparm_ch_int3:
|
|
stx num+1
|
|
sta num
|
|
jsr popa ; option character [TODO] pop just 1 byte, or 2?
|
|
jsr xgetparm_ch
|
|
getparm_return_int3:
|
|
bcs :+
|
|
; Result is in AXY, and we need to store it at (num) as 4 bytes
|
|
pha
|
|
tya
|
|
ldy #0
|
|
sta (num),y
|
|
txa
|
|
iny
|
|
sta (num),y
|
|
pla
|
|
iny
|
|
sta (num),y ; carry is still clear for no-error return
|
|
lda #0
|
|
iny
|
|
sta (num),y
|
|
: returnTrueForCLC
|
|
|
|
|
|
; extern _Bool __fastcall__ xgetparm_ch_byte(uint8_t optionCharacter, uint8_t* outValue); // filetype, devnum, yesno
|
|
.export _xgetparm_ch_byte
|
|
_xgetparm_ch_byte:
|
|
stx p+1
|
|
sta p
|
|
jsr popa ; option character [TODO] pop just 1 byte, or 2?
|
|
jsr xgetparm_ch ; 1-byte result in A (differs from int1)
|
|
bcs :+
|
|
ldy #0
|
|
sta (p),y
|
|
: returnTrueForCLC
|
|
|
|
|
|
; extern _Bool __fastcall__ xgetparm_n_int3(uint8_t index, uint32_t* outValue);
|
|
.export _xgetparm_n_int3
|
|
_xgetparm_n_int3:
|
|
stx num+1
|
|
sta num
|
|
jsr popa ; option character
|
|
jsr xgetparm_n
|
|
jmp getparm_return_int3 ;[TODO] Better to turn this into a library, and just let this code be not-linked-in
|
|
|
|
|
|
; extern _Bool __fastcall__ xgetparm_ch_string(uint8_t optionCharacter, uint8_t** outString);
|
|
; [TODO]
|
|
|
|
; extern _Bool __fastcall__ xgetparm_ch_path(uint8_t optionCharacter, uint8_t** outPath);
|
|
; [TODO]
|
|
|
|
; extern _Bool __fastcall__ xgetparm_ch_path_and_filetype(uint8_t optionCharacter, uint8_t** outPath, uint8_t* outFiletype);
|
|
; [TODO]
|
|
|
|
; extern _Bool __fastcall__ xgetparm_n_byte(uint8_t index, uint8_t* outValue); // int1, filetype, devnum, yesno
|
|
; [TODO]
|
|
|
|
; extern _Bool __fastcall__ xgetparm_n_int2(uint8_t index, uint16_t* outValue);
|
|
; [TODO]
|
|
|
|
; extern _Bool __fastcall__ xgetparm_n_string(uint8_t index, uint8_t** outString);
|
|
; [TODO]
|
|
|
|
; extern _Bool __fastcall__ xgetparm_n_path(uint8_t index, uint8_t** outPath);
|
|
.export _xgetparm_n_path
|
|
_xgetparm_n_path:
|
|
stx num+1
|
|
sta num
|
|
jsr popa ; param index number [TODO] pop just 1 byte, or 2?
|
|
jsr xgetparm_n ; 2-byte result in AY
|
|
bcs :+
|
|
; Result is in AY, and we need to store it at (num) as 2 bytes
|
|
tax
|
|
tya
|
|
ldy #0
|
|
sta (num),y
|
|
iny
|
|
txa
|
|
sta (num),y
|
|
: returnTrueForCLC
|
|
|
|
|
|
; extern _Bool __fastcall__ xgetparm_n_path_and_filetype(uint8_t index, uint8_t** outPath, uint8_t* outFiletype);
|
|
; [TODO]
|
|
|
|
|
|
; extern void __fastcall__ xmessage(const uint8_t*);
|
|
.export _xmessage
|
|
_xmessage:
|
|
; [TODO] export this from the shell as xmessage ?
|
|
stx loadCharacter+2
|
|
sta loadCharacter+1
|
|
ldy #0
|
|
loadCharacter: lda $7777,y ; operand modified
|
|
beq :+
|
|
ora #$80
|
|
jsr cout
|
|
iny
|
|
bne loadCharacter
|
|
inc loadCharacter+2
|
|
bne loadCharacter
|
|
: rts
|
|
|
|
; extern void __fastcall__ xprint_ftype(uint8_t); // print a filetype
|
|
.export _xprint_ftype
|
|
_xprint_ftype = xprint_ftype
|
|
|
|
; extern void __fastcall__ xprint_access(uint8_t); // print a ProDOS access byte (r/w/n/d/etc)
|
|
.export _xprint_access
|
|
_xprint_access = xprint_access
|
|
|
|
; extern void __fastcall__ xprdec_2(uint16_t); // print 2-byte value in decimal
|
|
.proc _xprdec_2
|
|
.export _xprdec_2
|
|
_xprdec_2:
|
|
tay
|
|
txa
|
|
jmp xprdec_2
|
|
.endproc
|
|
|
|
; extern void __fastcall__ xprdec_3(uint32_t); // print 3-byte value in decimal
|
|
.proc _xprdec_3
|
|
.export _xprdec_3
|
|
_xprdec_3:
|
|
sta xnum
|
|
stx xnum+1
|
|
lda sreg
|
|
sta xnum+2
|
|
jmp xprdec_3 ; wants A/X/Y
|
|
.endproc
|
|
|
|
; extern void __fastcall__ xprdec_pad(uint32_t); // print 3-byte value in decimal, right-justified in a 7-character field
|
|
.proc _xprdec_pad
|
|
.export _xprdec_pad
|
|
_xprdec_pad:
|
|
sta xnum
|
|
stx xnum+1
|
|
lda sreg
|
|
sta xnum+2
|
|
jmp xprdec_pad
|
|
.endproc
|
|
|
|
; extern void __fastcall__ xprint_path(const uint8_t*);
|
|
.proc _xprint_path
|
|
.export _xprint_path
|
|
_xprint_path:
|
|
tay
|
|
txa
|
|
jmp xprint_path
|
|
.endproc
|
|
|
|
; extern uint8_t* __fastcall__ xbuild_local(uint8_t* path); // builds a path relative to the "%" directory -- C uses XA
|
|
.proc _xbuild_local
|
|
.export _xbuild_local
|
|
_xbuild_local:
|
|
tay
|
|
txa
|
|
jsr xbuild_local ; input/output in AY
|
|
tax
|
|
tya
|
|
rts
|
|
.endproc
|
|
|
|
; extern void __fastcall__ xprint_sd(uint8_t slotAndDrive);
|
|
.export _xprint_sd
|
|
_xprint_sd = xprint_sd
|
|
|
|
; extern uint8_t __fastcall__ xredirect(int8_t adjustment);
|
|
.proc _xredirect
|
|
.export _xredirect
|
|
_xredirect:
|
|
jsr xredirect
|
|
ldx #0
|
|
rts
|
|
.endproc
|
|
|
|
; extern uint8_t __fastcall__ xpercent(uint32_t value, uint32_t total);
|
|
; [TODO] A/X/Y? and num+2,num+1,num
|
|
|
|
; extern _Bool __fastcall__ xyesno();
|
|
.proc _xyesno
|
|
.export _xyesno
|
|
_xyesno:
|
|
jsr xyesno
|
|
beq :+ ; beq = No (0), otherwise return 1
|
|
lda #1
|
|
: ldx #0
|
|
rts
|
|
.endproc
|
|
|
|
; extern uint8_t __fastcall__ xyesno2(uint8_t defaultChar); // v1.2
|
|
.proc _xyesno2
|
|
.export _xyesno2
|
|
_xyesno2:
|
|
jsr xyesno2
|
|
beq :+ ; beq = No (0), otherwise return 1
|
|
lda #1
|
|
: ldx #0
|
|
rts
|
|
.endproc
|
|
|
|
; extern _Bool __fastcall__ xgetln(); // result is in "string" (TODO: call it "xString" or something?)
|
|
.proc _xgetln
|
|
.export _xgetln
|
|
_xgetln:
|
|
jsr xgetln
|
|
returnTrueForCLC
|
|
.endproc
|
|
|
|
; extern void __fastcall__ xbell();
|
|
.export _xbell
|
|
_xbell = xbell
|
|
|
|
; extern uint8_t __fastcall__ xdowncase(uint8_t ch);
|
|
.proc _xdowncase
|
|
.export _xdowncase
|
|
_xdowncase:
|
|
jsr xdowncase
|
|
ldx #0
|
|
rts
|
|
.endproc
|
|
|
|
; extern void __fastcall__ xplural(uint16_t value);
|
|
.proc _xplural
|
|
.export _xplural
|
|
_xplural:
|
|
tay
|
|
txa
|
|
jmp xplural ; wants AY
|
|
.endproc
|
|
|
|
; extern _Bool __fastcall__ xcheck_wait();
|
|
.proc _xcheck_wait
|
|
.export _xcheck_wait
|
|
_xcheck_wait:
|
|
jsr xcheck_wait
|
|
returnTrueForCLC
|
|
.endproc
|
|
|
|
; extern void __fastcall__ xpr_date(uint16_t date);
|
|
.proc _xpr_date
|
|
.export _xpr_date
|
|
_xpr_date:
|
|
tay
|
|
txa
|
|
jmp xpr_date_ay
|
|
.endproc
|
|
|
|
; extern void __fastcall__ xpr_time(uint16_t time);
|
|
.proc _xpr_time
|
|
.export _xpr_time
|
|
_xpr_time:
|
|
tay
|
|
txa
|
|
jmp xpr_time_ay
|
|
.endproc
|
|
|
|
; extern void __fastcall__ xProDOS_err(uint8_t err); // does not return
|
|
.export _xProDOS_err
|
|
_xProDOS_err = xProDOS_err
|
|
|
|
; extern void __fastcall__ xProDOS_er(uint8_t err);
|
|
.export _xProDOS_er
|
|
_xProDOS_er = xProDOS_er
|
|
|
|
; extern void __fastcall__ xerr(); // does not return
|
|
.export _xerr
|
|
_xerr = xerr
|
|
|
|
; extern void __fastcall__ xprdec_pad_n(uint32_t value, uint8_t widthMinusOne);
|
|
; [TODO]
|
|
|
|
; extern void __fastcall__ xdir_setup(uint8_t* path); // path is complete, or relative to the prefix (see xdir_setup2)
|
|
.proc _xdir_setup
|
|
.export _xdir_setup
|
|
_xdir_setup:
|
|
tay
|
|
txa
|
|
jmp xdir_setup
|
|
.endproc
|
|
|
|
; extern void __fastcall__ xdir_setup2(uint8_t* path); // v1.23 - path is complete, or relative to the already-open directory
|
|
.proc _xdir_setup2
|
|
.export _xdir_setup2
|
|
_xdir_setup2:
|
|
tay
|
|
txa
|
|
jmp xdir_setup2
|
|
.endproc
|
|
|
|
; extern void __fastcall__ xdir_finish();
|
|
.export _xdir_finish
|
|
_xdir_finish = xdir_finish
|
|
|
|
; extern _Bool __fastcall__ xread1dir(); // if returns true, result is in "catbuff"
|
|
.proc _read1dir
|
|
.export _xread1dir
|
|
_xread1dir:
|
|
jsr xread1dir
|
|
returnTrueForCLC
|
|
.endproc
|
|
|
|
; extern void __fastcall__ xpoll_io();
|
|
.export _xpoll_io
|
|
_xpoll_io = xpoll_io
|
|
|
|
; extern void __fastcall__ xprint_ver(uint8_t version);
|
|
.export _xprint_ver
|
|
_xprint_ver = xprint_ver
|
|
|
|
; extern void __fastcall__ xpush_level(); // call before dir_setup
|
|
.export _xpush_level
|
|
_xpush_level = xpush_level
|
|
|
|
; extern _Bool __fastcall__ xfman_open(uint8_t* path, uint8_t* outRefnumOrError);
|
|
; [TODO]
|
|
; extern _Bool __fastcall__ xfman_read(uint8_t refnum, uint8_t* outCharOrError);
|
|
; [TODO]
|
|
|
|
; extern uint8_t __fastcall__ xrdkey(); // ;v1.1
|
|
.export _xrdkey
|
|
_xrdkey = xrdkey
|
|
|
|
; extern void __fastcall__ xdirty(); // v1.1
|
|
.export _xdirty
|
|
_xdirty = xdirty
|
|
|
|
; extern uint8_t __fastcall__ xgetnump(); // v1.1
|
|
.proc _xgetnump
|
|
.export _xgetnump
|
|
_xgetnump:
|
|
jsr xgetnump
|
|
ldx #0 ;extend result to 16 bits
|
|
rts
|
|
.endproc
|
|
|
|
; extern uint8_t __fastcall__ ProDOS(uint8_t call, void* params);
|
|
.proc _ProDOS
|
|
.export _ProDOS
|
|
;;_ProDOS:
|
|
stx @params+1
|
|
sta @params
|
|
jsr popa
|
|
sta @callNum
|
|
jsr mli
|
|
@callNum: .byte 0
|
|
@params: .addr 0
|
|
ldx #0 ; error in A
|
|
rts
|
|
.endproc
|
|
|
|
.segment "ONCE"
|
|
.segment "INIT"
|