1
0
mirror of https://github.com/cc65/cc65.git synced 2026-04-25 06:17:58 +00:00

Removed (pretty inconsistently used) tab chars from source code base.

This commit is contained in:
Oliver Schmidt
2013-05-09 13:56:54 +02:00
parent 44fd1082ae
commit 85885001b1
1773 changed files with 62864 additions and 62868 deletions
+4 -4
View File
@@ -4,14 +4,14 @@
; Screen size variables
;
.export screensize
.export screensize
.include "apple2.inc"
screensize:
ldx WNDWDTH
lda WNDBTM
ldx WNDWDTH
lda WNDBTM
sec
sbc WNDTOP
sbc WNDTOP
tay
rts
+57 -57
View File
@@ -5,14 +5,14 @@
; void reset_brk (void);
;
.export _set_brk, _reset_brk
.destructor _reset_brk
.export _set_brk, _reset_brk
.destructor _reset_brk
; Be sure to export the following variables absolute
.export _brk_a: abs, _brk_x: abs, _brk_y: abs
.export _brk_a: abs, _brk_x: abs, _brk_y: abs
.export _brk_sr: abs, _brk_pc: abs
.include "apple2.inc"
.include "apple2.inc"
_brk_a = $45
_brk_x = $46
@@ -22,51 +22,51 @@ _brk_sp = $49
_brk_pc = $3A
.bss
oldvec: .res 2 ; Old vector
oldvec: .res 2 ; Old vector
.data
uservec: jmp $FFFF ; Patched at runtime
uservec: jmp $FFFF ; Patched at runtime
.code
; Set the break vector
.proc _set_brk
.proc _set_brk
sta uservec+1
stx uservec+2 ; Set the user vector
sta uservec+1
stx uservec+2 ; Set the user vector
lda oldvec
ora oldvec+1 ; Did we save the vector already?
bne L1 ; Jump if we installed the handler already
lda oldvec
ora oldvec+1 ; Did we save the vector already?
bne L1 ; Jump if we installed the handler already
lda BRKVec
sta oldvec
lda BRKVec+1
sta oldvec+1 ; Save the old vector
lda BRKVec
sta oldvec
lda BRKVec+1
sta oldvec+1 ; Save the old vector
L1: lda #<brk_handler ; Set the break vector to our routine
ldx #>brk_handler
sta BRKVec
stx BRKVec+1
rts
L1: lda #<brk_handler ; Set the break vector to our routine
ldx #>brk_handler
sta BRKVec
stx BRKVec+1
rts
.endproc
; Reset the break vector
.proc _reset_brk
.proc _reset_brk
lda oldvec
ldx oldvec+1
beq @L9 ; Jump if vector not installed
sta BRKVec
stx BRKVec+1
lda #$00
sta oldvec ; Clear the old vector
stx oldvec+1
@L9: rts
lda oldvec
ldx oldvec+1
beq @L9 ; Jump if vector not installed
sta BRKVec
stx BRKVec+1
lda #$00
sta oldvec ; Clear the old vector
stx oldvec+1
@L9: rts
.endproc
@@ -74,39 +74,39 @@ L1: lda #<brk_handler ; Set the break vector to our routine
; Break handler, called if a break occurs
.proc brk_handler
.proc brk_handler
sec
lda _brk_pc
sbc #$02 ; Point to start of brk
sta _brk_pc
lda _brk_pc+1
sbc #$00
sta _brk_pc+1
sec
lda _brk_pc
sbc #$02 ; Point to start of brk
sta _brk_pc
lda _brk_pc+1
sbc #$00
sta _brk_pc+1
clc
lda _brk_sp
adc #$04 ; Adjust stack pointer
sta _brk_sp
clc
lda _brk_sp
adc #$04 ; Adjust stack pointer
sta _brk_sp
lda _brk_sr ; Clear brk
and #$EF
sta _brk_sr
lda _brk_sr ; Clear brk
and #$EF
sta _brk_sr
jsr uservec ; Call the user's routine
jsr uservec ; Call the user's routine
lda _brk_pc+1
pha
lda _brk_pc
pha
lda _brk_sr
pha
lda _brk_pc+1
pha
lda _brk_pc
pha
lda _brk_sr
pha
ldx _brk_x
ldy _brk_y
lda _brk_a
ldx _brk_x
ldy _brk_y
lda _brk_a
rti ; Jump back...
rti ; Jump back...
.endproc
+8 -8
View File
@@ -5,15 +5,15 @@
; void __fastcall__ cclear (unsigned char length);
;
.export _cclearxy, _cclear
.import popa, _gotoxy, chlinedirect
.export _cclearxy, _cclear
.import popa, _gotoxy, chlinedirect
_cclearxy:
pha ; Save the length
jsr popa ; Get y
jsr _gotoxy ; Call this one, will pop params
pla ; Restore the length and run into _cclear
pha ; Save the length
jsr popa ; Get y
jsr _gotoxy ; Call this one, will pop params
pla ; Restore the length and run into _cclear
_cclear:
ldx #' ' | $80 ; Blank, screen code
jmp chlinedirect
ldx #' ' | $80 ; Blank, screen code
jmp chlinedirect
+5 -5
View File
@@ -12,14 +12,14 @@
_cgetc:
lda KBD
bpl _cgetc ; If < 128, no key pressed
bpl _cgetc ; If < 128, no key pressed
; At this time, the high bit of the key pressed is set
bit KBDSTRB ; Clear keyboard strobe
bit KBDSTRB ; Clear keyboard strobe
.ifdef __APPLE2ENH__
bit BUTN0 ; Check if OpenApple is down
bit BUTN0 ; Check if OpenApple is down
bmi done
.endif
and #$7F ; If not down, then clear high bit
done: ldx #$00
and #$7F ; If not down, then clear high bit
done: ldx #$00
rts
+21 -21
View File
@@ -5,33 +5,33 @@
; void __fastcall__ chline (unsigned char length);
;
.export _chlinexy, _chline, chlinedirect
.import popa, _gotoxy, cputdirect
.export _chlinexy, _chline, chlinedirect
.import popa, _gotoxy, cputdirect
.include "zeropage.inc"
.include "apple2.inc"
.include "zeropage.inc"
.include "apple2.inc"
_chlinexy:
pha ; Save the length
jsr popa ; Get y
jsr _gotoxy ; Call this one, will pop params
pla ; Restore the length and run into _chline
pha ; Save the length
jsr popa ; Get y
jsr _gotoxy ; Call this one, will pop params
pla ; Restore the length and run into _chline
_chline:
.ifdef __APPLE2ENH__
ldx #'S' ; MouseText character
ldy INVFLG
cpy #$FF ; Normal character display mode?
beq chlinedirect
.ifdef __APPLE2ENH__
ldx #'S' ; MouseText character
ldy INVFLG
cpy #$FF ; Normal character display mode?
beq chlinedirect
.endif
ldx #'-' | $80 ; Horizontal line, screen code
ldx #'-' | $80 ; Horizontal line, screen code
chlinedirect:
cmp #$00 ; Is the length zero?
beq done ; Jump if done
sta tmp1
: txa ; Screen code
jsr cputdirect ; Direct output
dec tmp1
bne :-
cmp #$00 ; Is the length zero?
beq done ; Jump if done
sta tmp1
: txa ; Screen code
jsr cputdirect ; Direct output
dec tmp1
bne :-
done: rts
+15 -15
View File
@@ -4,37 +4,37 @@
; int __fastcall__ close (int fd);
;
.export _close
.export _close
.import closedirect, freebuffer
.import closedirect, freebuffer
.include "errno.inc"
.include "filedes.inc"
.include "errno.inc"
.include "filedes.inc"
_close:
; Process fd
jsr getfd ; Returns A, Y and C
bcs errno
jsr getfd ; Returns A, Y and C
bcs errno
; Check for device
bmi zerofd
bmi zerofd
; Close file
jsr closedirect ; Preserves Y
bcs oserr
jsr closedirect ; Preserves Y
bcs oserr
; Mark fdtab slot as free
zerofd: lda #$00
sta fdtab + FD::REF_NUM,y
zerofd: lda #$00
sta fdtab + FD::REF_NUM,y
; Cleanup I/O buffer
jsr freebuffer
jsr freebuffer
; Return success
lda #$00
lda #$00
; Set __oserror
oserr: jmp __mappederrno
oserr: jmp __mappederrno
; Set __errno
errno: jmp __directerrno
errno: jmp __directerrno
+1 -1
View File
@@ -38,7 +38,7 @@
/*****************************************************************************/
/* Code */
/* Code */
/*****************************************************************************/
+2 -2
View File
@@ -4,7 +4,7 @@
; void clrscr (void);
;
.export _clrscr
.import HOME
.export _clrscr
.import HOME
_clrscr := HOME
+2 -2
View File
@@ -6,8 +6,8 @@
; unsigned char __fastcall__ bordercolor (unsigned char color);
;
.export _textcolor, _bgcolor, _bordercolor
.import return0, return1
.export _textcolor, _bgcolor, _bordercolor
.import return0, return1
_textcolor := return1
+9 -9
View File
@@ -4,17 +4,17 @@
; COUT routine
;
.export COUT
.export COUT
.include "apple2.inc"
.include "apple2.inc"
.segment "LOWCODE"
.segment "LOWCODE"
COUT:
; Switch in ROM and call COUT
bit $C082
jsr $FDED ; Vector to user output routine
; Switch in ROM and call COUT
bit $C082
jsr $FDED ; Vector to user output routine
; Switch in LC bank 2 for R/O and return
bit $C080
rts
; Switch in LC bank 2 for R/O and return
bit $C080
rts
+1 -1
View File
@@ -19,7 +19,7 @@
.ifdef __APPLE2ENH__
initconio:
sta SETALTCHAR ; Switch in alternate charset
bit LORES ; Limit SET80COL-HISCR to text
bit LORES ; Limit SET80COL-HISCR to text
rts
.endif
+130 -130
View File
@@ -4,7 +4,7 @@
; Character specification table.
;
.include "ctype.inc"
.include "ctype.inc"
; The tables are readonly, put them into the rodata segment
@@ -26,136 +26,136 @@
__ctype:
.repeat 2
.byte CT_CTRL ; 0/00 ___ctrl_@___
.byte CT_CTRL ; 1/01 ___ctrl_A___
.byte CT_CTRL ; 2/02 ___ctrl_B___
.byte CT_CTRL ; 3/03 ___ctrl_C___
.byte CT_CTRL ; 4/04 ___ctrl_D___
.byte CT_CTRL ; 5/05 ___ctrl_E___
.byte CT_CTRL ; 6/06 ___ctrl_F___
.byte CT_CTRL ; 7/07 ___ctrl_G___
.byte CT_CTRL ; 8/08 ___ctrl_H___
.byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB
; 9/09 ___ctrl_I___
.byte CT_CTRL | CT_OTHER_WS ; 10/0a ___ctrl_J___
.byte CT_CTRL | CT_OTHER_WS ; 11/0b ___ctrl_K___
.byte CT_CTRL | CT_OTHER_WS ; 12/0c ___ctrl_L___
.byte CT_CTRL | CT_OTHER_WS ; 13/0d ___ctrl_M___
.byte CT_CTRL ; 14/0e ___ctrl_N___
.byte CT_CTRL ; 15/0f ___ctrl_O___
.byte CT_CTRL ; 16/10 ___ctrl_P___
.byte CT_CTRL ; 17/11 ___ctrl_Q___
.byte CT_CTRL ; 18/12 ___ctrl_R___
.byte CT_CTRL ; 19/13 ___ctrl_S___
.byte CT_CTRL ; 20/14 ___ctrl_T___
.byte CT_CTRL ; 21/15 ___ctrl_U___
.byte CT_CTRL ; 22/16 ___ctrl_V___
.byte CT_CTRL ; 23/17 ___ctrl_W___
.byte CT_CTRL ; 24/18 ___ctrl_X___
.byte CT_CTRL ; 25/19 ___ctrl_Y___
.byte CT_CTRL ; 26/1a ___ctrl_Z___
.byte CT_CTRL ; 27/1b ___ctrl_[___
.byte CT_CTRL ; 28/1c ___ctrl_\___
.byte CT_CTRL ; 29/1d ___ctrl_]___
.byte CT_CTRL ; 30/1e ___ctrl_^___
.byte CT_CTRL ; 31/1f ___ctrl_____
.byte CT_SPACE | CT_SPACE_TAB ; 32/20 ___SPACE___
.byte CT_NONE ; 33/21 _____!_____
.byte CT_NONE ; 34/22 _____"_____
.byte CT_NONE ; 35/23 _____#_____
.byte CT_NONE ; 36/24 _____$_____
.byte CT_NONE ; 37/25 _____%_____
.byte CT_NONE ; 38/26 _____&_____
.byte CT_NONE ; 39/27 _____'_____
.byte CT_NONE ; 40/28 _____(_____
.byte CT_NONE ; 41/29 _____)_____
.byte CT_NONE ; 42/2a _____*_____
.byte CT_NONE ; 43/2b _____+_____
.byte CT_NONE ; 44/2c _____,_____
.byte CT_NONE ; 45/2d _____-_____
.byte CT_NONE ; 46/2e _____._____
.byte CT_NONE ; 47/2f _____/_____
.byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____
.byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____
.byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____
.byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____
.byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____
.byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____
.byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____
.byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____
.byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____
.byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____
.byte CT_NONE ; 58/3a _____:_____
.byte CT_NONE ; 59/3b _____;_____
.byte CT_NONE ; 60/3c _____<_____
.byte CT_NONE ; 61/3d _____=_____
.byte CT_NONE ; 62/3e _____>_____
.byte CT_NONE ; 63/3f _____?_____
.byte CT_CTRL ; 0/00 ___ctrl_@___
.byte CT_CTRL ; 1/01 ___ctrl_A___
.byte CT_CTRL ; 2/02 ___ctrl_B___
.byte CT_CTRL ; 3/03 ___ctrl_C___
.byte CT_CTRL ; 4/04 ___ctrl_D___
.byte CT_CTRL ; 5/05 ___ctrl_E___
.byte CT_CTRL ; 6/06 ___ctrl_F___
.byte CT_CTRL ; 7/07 ___ctrl_G___
.byte CT_CTRL ; 8/08 ___ctrl_H___
.byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB
; 9/09 ___ctrl_I___
.byte CT_CTRL | CT_OTHER_WS ; 10/0a ___ctrl_J___
.byte CT_CTRL | CT_OTHER_WS ; 11/0b ___ctrl_K___
.byte CT_CTRL | CT_OTHER_WS ; 12/0c ___ctrl_L___
.byte CT_CTRL | CT_OTHER_WS ; 13/0d ___ctrl_M___
.byte CT_CTRL ; 14/0e ___ctrl_N___
.byte CT_CTRL ; 15/0f ___ctrl_O___
.byte CT_CTRL ; 16/10 ___ctrl_P___
.byte CT_CTRL ; 17/11 ___ctrl_Q___
.byte CT_CTRL ; 18/12 ___ctrl_R___
.byte CT_CTRL ; 19/13 ___ctrl_S___
.byte CT_CTRL ; 20/14 ___ctrl_T___
.byte CT_CTRL ; 21/15 ___ctrl_U___
.byte CT_CTRL ; 22/16 ___ctrl_V___
.byte CT_CTRL ; 23/17 ___ctrl_W___
.byte CT_CTRL ; 24/18 ___ctrl_X___
.byte CT_CTRL ; 25/19 ___ctrl_Y___
.byte CT_CTRL ; 26/1a ___ctrl_Z___
.byte CT_CTRL ; 27/1b ___ctrl_[___
.byte CT_CTRL ; 28/1c ___ctrl_\___
.byte CT_CTRL ; 29/1d ___ctrl_]___
.byte CT_CTRL ; 30/1e ___ctrl_^___
.byte CT_CTRL ; 31/1f ___ctrl_____
.byte CT_SPACE | CT_SPACE_TAB ; 32/20 ___SPACE___
.byte CT_NONE ; 33/21 _____!_____
.byte CT_NONE ; 34/22 _____"_____
.byte CT_NONE ; 35/23 _____#_____
.byte CT_NONE ; 36/24 _____$_____
.byte CT_NONE ; 37/25 _____%_____
.byte CT_NONE ; 38/26 _____&_____
.byte CT_NONE ; 39/27 _____'_____
.byte CT_NONE ; 40/28 _____(_____
.byte CT_NONE ; 41/29 _____)_____
.byte CT_NONE ; 42/2a _____*_____
.byte CT_NONE ; 43/2b _____+_____
.byte CT_NONE ; 44/2c _____,_____
.byte CT_NONE ; 45/2d _____-_____
.byte CT_NONE ; 46/2e _____._____
.byte CT_NONE ; 47/2f _____/_____
.byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____
.byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____
.byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____
.byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____
.byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____
.byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____
.byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____
.byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____
.byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____
.byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____
.byte CT_NONE ; 58/3a _____:_____
.byte CT_NONE ; 59/3b _____;_____
.byte CT_NONE ; 60/3c _____<_____
.byte CT_NONE ; 61/3d _____=_____
.byte CT_NONE ; 62/3e _____>_____
.byte CT_NONE ; 63/3f _____?_____
.byte CT_NONE ; 64/40 _____@_____
.byte CT_UPPER | CT_XDIGIT ; 65/41 _____A_____
.byte CT_UPPER | CT_XDIGIT ; 66/42 _____B_____
.byte CT_UPPER | CT_XDIGIT ; 67/43 _____C_____
.byte CT_UPPER | CT_XDIGIT ; 68/44 _____D_____
.byte CT_UPPER | CT_XDIGIT ; 69/45 _____E_____
.byte CT_UPPER | CT_XDIGIT ; 70/46 _____F_____
.byte CT_UPPER ; 71/47 _____G_____
.byte CT_UPPER ; 72/48 _____H_____
.byte CT_UPPER ; 73/49 _____I_____
.byte CT_UPPER ; 74/4a _____J_____
.byte CT_UPPER ; 75/4b _____K_____
.byte CT_UPPER ; 76/4c _____L_____
.byte CT_UPPER ; 77/4d _____M_____
.byte CT_UPPER ; 78/4e _____N_____
.byte CT_UPPER ; 79/4f _____O_____
.byte CT_UPPER ; 80/50 _____P_____
.byte CT_UPPER ; 81/51 _____Q_____
.byte CT_UPPER ; 82/52 _____R_____
.byte CT_UPPER ; 83/53 _____S_____
.byte CT_UPPER ; 84/54 _____T_____
.byte CT_UPPER ; 85/55 _____U_____
.byte CT_UPPER ; 86/56 _____V_____
.byte CT_UPPER ; 87/57 _____W_____
.byte CT_UPPER ; 88/58 _____X_____
.byte CT_UPPER ; 89/59 _____Y_____
.byte CT_UPPER ; 90/5a _____Z_____
.byte CT_NONE ; 91/5b _____[_____
.byte CT_NONE ; 92/5c _____\_____
.byte CT_NONE ; 93/5d _____]_____
.byte CT_NONE ; 94/5e _____^_____
.byte CT_NONE ; 95/5f _UNDERLINE_
.byte CT_NONE ; 96/60 ___grave___
.byte CT_LOWER | CT_XDIGIT ; 97/61 _____a_____
.byte CT_LOWER | CT_XDIGIT ; 98/62 _____b_____
.byte CT_LOWER | CT_XDIGIT ; 99/63 _____c_____
.byte CT_LOWER | CT_XDIGIT ; 100/64 _____d_____
.byte CT_LOWER | CT_XDIGIT ; 101/65 _____e_____
.byte CT_LOWER | CT_XDIGIT ; 102/66 _____f_____
.byte CT_LOWER ; 103/67 _____g_____
.byte CT_LOWER ; 104/68 _____h_____
.byte CT_LOWER ; 105/69 _____i_____
.byte CT_LOWER ; 106/6a _____j_____
.byte CT_LOWER ; 107/6b _____k_____
.byte CT_LOWER ; 108/6c _____l_____
.byte CT_LOWER ; 109/6d _____m_____
.byte CT_LOWER ; 110/6e _____n_____
.byte CT_LOWER ; 111/6f _____o_____
.byte CT_LOWER ; 112/70 _____p_____
.byte CT_LOWER ; 113/71 _____q_____
.byte CT_LOWER ; 114/72 _____r_____
.byte CT_LOWER ; 115/73 _____s_____
.byte CT_LOWER ; 116/74 _____t_____
.byte CT_LOWER ; 117/75 _____u_____
.byte CT_LOWER ; 118/76 _____v_____
.byte CT_LOWER ; 119/77 _____w_____
.byte CT_LOWER ; 120/78 _____x_____
.byte CT_LOWER ; 121/79 _____y_____
.byte CT_LOWER ; 122/7a _____z_____
.byte CT_NONE ; 123/7b _____{_____
.byte CT_NONE ; 124/7c _____|_____
.byte CT_NONE ; 125/7d _____}_____
.byte CT_NONE ; 126/7e _____~_____
.byte CT_OTHER_WS ; 127/7f ____DEL____
.byte CT_NONE ; 64/40 _____@_____
.byte CT_UPPER | CT_XDIGIT ; 65/41 _____A_____
.byte CT_UPPER | CT_XDIGIT ; 66/42 _____B_____
.byte CT_UPPER | CT_XDIGIT ; 67/43 _____C_____
.byte CT_UPPER | CT_XDIGIT ; 68/44 _____D_____
.byte CT_UPPER | CT_XDIGIT ; 69/45 _____E_____
.byte CT_UPPER | CT_XDIGIT ; 70/46 _____F_____
.byte CT_UPPER ; 71/47 _____G_____
.byte CT_UPPER ; 72/48 _____H_____
.byte CT_UPPER ; 73/49 _____I_____
.byte CT_UPPER ; 74/4a _____J_____
.byte CT_UPPER ; 75/4b _____K_____
.byte CT_UPPER ; 76/4c _____L_____
.byte CT_UPPER ; 77/4d _____M_____
.byte CT_UPPER ; 78/4e _____N_____
.byte CT_UPPER ; 79/4f _____O_____
.byte CT_UPPER ; 80/50 _____P_____
.byte CT_UPPER ; 81/51 _____Q_____
.byte CT_UPPER ; 82/52 _____R_____
.byte CT_UPPER ; 83/53 _____S_____
.byte CT_UPPER ; 84/54 _____T_____
.byte CT_UPPER ; 85/55 _____U_____
.byte CT_UPPER ; 86/56 _____V_____
.byte CT_UPPER ; 87/57 _____W_____
.byte CT_UPPER ; 88/58 _____X_____
.byte CT_UPPER ; 89/59 _____Y_____
.byte CT_UPPER ; 90/5a _____Z_____
.byte CT_NONE ; 91/5b _____[_____
.byte CT_NONE ; 92/5c _____\_____
.byte CT_NONE ; 93/5d _____]_____
.byte CT_NONE ; 94/5e _____^_____
.byte CT_NONE ; 95/5f _UNDERLINE_
.byte CT_NONE ; 96/60 ___grave___
.byte CT_LOWER | CT_XDIGIT ; 97/61 _____a_____
.byte CT_LOWER | CT_XDIGIT ; 98/62 _____b_____
.byte CT_LOWER | CT_XDIGIT ; 99/63 _____c_____
.byte CT_LOWER | CT_XDIGIT ; 100/64 _____d_____
.byte CT_LOWER | CT_XDIGIT ; 101/65 _____e_____
.byte CT_LOWER | CT_XDIGIT ; 102/66 _____f_____
.byte CT_LOWER ; 103/67 _____g_____
.byte CT_LOWER ; 104/68 _____h_____
.byte CT_LOWER ; 105/69 _____i_____
.byte CT_LOWER ; 106/6a _____j_____
.byte CT_LOWER ; 107/6b _____k_____
.byte CT_LOWER ; 108/6c _____l_____
.byte CT_LOWER ; 109/6d _____m_____
.byte CT_LOWER ; 110/6e _____n_____
.byte CT_LOWER ; 111/6f _____o_____
.byte CT_LOWER ; 112/70 _____p_____
.byte CT_LOWER ; 113/71 _____q_____
.byte CT_LOWER ; 114/72 _____r_____
.byte CT_LOWER ; 115/73 _____s_____
.byte CT_LOWER ; 116/74 _____t_____
.byte CT_LOWER ; 117/75 _____u_____
.byte CT_LOWER ; 118/76 _____v_____
.byte CT_LOWER ; 119/77 _____w_____
.byte CT_LOWER ; 120/78 _____x_____
.byte CT_LOWER ; 121/79 _____y_____
.byte CT_LOWER ; 122/7a _____z_____
.byte CT_NONE ; 123/7b _____{_____
.byte CT_NONE ; 124/7c _____|_____
.byte CT_NONE ; 125/7d _____}_____
.byte CT_NONE ; 126/7e _____~_____
.byte CT_OTHER_WS ; 127/7f ____DEL____
.endrepeat
+18 -18
View File
@@ -5,31 +5,31 @@
; void __fastcall__ cvline (unsigned char length);
;
.export _cvlinexy, _cvline, cvlinedirect
.import popa, _gotoxy, putchar, newline
.export _cvlinexy, _cvline, cvlinedirect
.import popa, _gotoxy, putchar, newline
.include "zeropage.inc"
.include "zeropage.inc"
_cvlinexy:
pha ; Save the length
jsr popa ; Get y
jsr _gotoxy ; Call this one, will pop params
pla ; Restore the length and run into _cvline
pha ; Save the length
jsr popa ; Get y
jsr _gotoxy ; Call this one, will pop params
pla ; Restore the length and run into _cvline
_cvline:
.ifdef __APPLE2ENH__
ldx #'|' | $80 ; Vertical line, screen code
.ifdef __APPLE2ENH__
ldx #'|' | $80 ; Vertical line, screen code
.else
ldx #'!' | $80 ; Vertical line, screen code
ldx #'!' | $80 ; Vertical line, screen code
.endif
cvlinedirect:
cmp #$00 ; Is the length zero?
beq done ; Jump if done
sta tmp1
: txa ; Screen code
jsr putchar ; Write, no cursor advance
jsr newline ; Advance cursor to next line
dec tmp1
bne :-
cmp #$00 ; Is the length zero?
beq done ; Jump if done
sta tmp1
: txa ; Screen code
jsr putchar ; Write, no cursor advance
jsr newline ; Advance cursor to next line
dec tmp1
bne :-
done: rts
+42 -42
View File
@@ -4,79 +4,79 @@
; char* __fastcall__ getdevicedir (unsigned char device, char* buf, size_t size);
;
.export _getdevicedir
.import popax, popa
.export _getdevicedir
.import popax, popa
.include "zeropage.inc"
.include "errno.inc"
.include "mli.inc"
.include "zeropage.inc"
.include "errno.inc"
.include "mli.inc"
_getdevicedir:
; Save size
sta ptr2
stx ptr2+1
sta ptr2
stx ptr2+1
; Save buf
jsr popax
sta ptr1
stx ptr1+1
jsr popax
sta ptr1
stx ptr1+1
; Set buf
sta mliparam + MLI::ON_LINE::DATA_BUFFER
stx mliparam + MLI::ON_LINE::DATA_BUFFER+1
sta mliparam + MLI::ON_LINE::DATA_BUFFER
stx mliparam + MLI::ON_LINE::DATA_BUFFER+1
; Set device
jsr popa
jsr popa
asl
asl
asl
asl
sta mliparam + MLI::ON_LINE::UNIT_NUM
sta mliparam + MLI::ON_LINE::UNIT_NUM
; Check for valid slot
and #$70
beq erange
and #$70
beq erange
; Check for sufficient buf size
lda ptr2+1
bne :++ ; Buf >= 256
lda ptr2
cmp #17
bcs :++ ; Buf >= 17
lda ptr2+1
bne :++ ; Buf >= 256
lda ptr2
cmp #17
bcs :++ ; Buf >= 17
; Handle errors
erange: lda #<ERANGE
jsr __directerrno
bne :+ ; Branch always
oserr: jsr __mappederrno
: lda #$00 ; Return NULL
erange: lda #<ERANGE
jsr __directerrno
bne :+ ; Branch always
oserr: jsr __mappederrno
: lda #$00 ; Return NULL
tax
rts
; Get volume name
: lda #ON_LINE_CALL
ldx #ON_LINE_COUNT
jsr callmli
bcs oserr
: lda #ON_LINE_CALL
ldx #ON_LINE_COUNT
jsr callmli
bcs oserr
; Get volume name length
ldy #$00
lda (ptr1),y
and #15 ; Max volume name length
sta tmp1
ldy #$00
lda (ptr1),y
and #15 ; Max volume name length
sta tmp1
; Add leading slash
lda #'/'
sta (ptr1),y
lda #'/'
sta (ptr1),y
; Add terminating zero
ldy tmp1
ldy tmp1
iny
lda #$00
sta (ptr1),y
sta __oserror ; Clear _oserror
lda #$00
sta (ptr1),y
sta __oserror ; Clear _oserror
; Success, return buf
lda ptr1
ldx ptr1+1
lda ptr1
ldx ptr1+1
rts
+4 -4
View File
@@ -4,9 +4,9 @@
; unsigned char __fastcall__ dio_close (dhandle_t handle);
;
.export _dio_close
.import dioepilog
.export _dio_close
.import dioepilog
_dio_close:
lda #$00
jmp dioepilog
lda #$00
jmp dioepilog
+14 -14
View File
@@ -2,34 +2,34 @@
; Oliver Schmidt, 24.03.2005
;
.export dioprolog, diocommon, dioepilog
.import popax
.export dioprolog, diocommon, dioepilog
.import popax
.include "errno.inc"
.include "mli.inc"
.include "errno.inc"
.include "mli.inc"
dioprolog:
; Set buffer
sta mliparam + MLI::RW_BLOCK::DATA_BUFFER
stx mliparam + MLI::RW_BLOCK::DATA_BUFFER+1
sta mliparam + MLI::RW_BLOCK::DATA_BUFFER
stx mliparam + MLI::RW_BLOCK::DATA_BUFFER+1
; Get and set sect_num
jsr popax
sta mliparam + MLI::RW_BLOCK::BLOCK_NUM
stx mliparam + MLI::RW_BLOCK::BLOCK_NUM+1
jsr popax
sta mliparam + MLI::RW_BLOCK::BLOCK_NUM
stx mliparam + MLI::RW_BLOCK::BLOCK_NUM+1
; Get and set handle
jsr popax
sta mliparam + MLI::RW_BLOCK::UNIT_NUM
jsr popax
sta mliparam + MLI::RW_BLOCK::UNIT_NUM
rts
diocommon:
; Call read_block or write_block
ldx #RW_BLOCK_COUNT
jsr callmli
ldx #RW_BLOCK_COUNT
jsr callmli
dioepilog:
; Return success or error
sta __oserror
ldx #$00
ldx #$00
rts
+15 -15
View File
@@ -4,28 +4,28 @@
; dhandle_t __fastcall__ dio_open (unsigned char device);
;
.export _dio_open
.import return0, __dos_type, isdevice
.export _dio_open
.import return0, __dos_type, isdevice
.include "errno.inc"
.include "mli.inc"
.include "errno.inc"
.include "mli.inc"
_dio_open:
; Check for ProDOS 8
ldx __dos_type
bne :+
lda #$01 ; "Bad system call number"
bne oserr ; Branch always
ldx __dos_type
bne :+
lda #$01 ; "Bad system call number"
bne oserr ; Branch always
; Check for valid device
: tax
jsr isdevice
beq :+
lda #$28 ; "No device connected"
jsr isdevice
beq :+
lda #$28 ; "No device connected"
; Return oserror
oserr: sta __oserror
jmp return0
oserr: sta __oserror
jmp return0
; Return success
: txa
@@ -33,6 +33,6 @@ oserr: sta __oserror
asl
asl
asl
ldx #$00
stx __oserror
ldx #$00
stx __oserror
rts
+6 -6
View File
@@ -4,12 +4,12 @@
; unsigned char __fastcall__ dio_read (dhandle_t handle, unsigned sect_num, void *buffer);
;
.export _dio_read
.import dioprolog, diocommon
.export _dio_read
.import dioprolog, diocommon
.include "mli.inc"
.include "mli.inc"
_dio_read:
jsr dioprolog
lda #READ_BLOCK_CALL
jmp diocommon
jsr dioprolog
lda #READ_BLOCK_CALL
jmp diocommon
+41 -41
View File
@@ -4,39 +4,39 @@
; unsigned __fastcall__ dio_query_sectcount (dhandle_t handle);
;
.export _dio_query_sectcount
.import _dio_query_sectsize, _malloc, _free
.export _dio_query_sectcount
.import _dio_query_sectsize, _malloc, _free
.include "zeropage.inc"
.include "errno.inc"
.include "mli.inc"
.include "zeropage.inc"
.include "errno.inc"
.include "mli.inc"
_dio_query_sectcount:
; Set handle
sta mliparam + MLI::ON_LINE::UNIT_NUM
sta mliparam + MLI::ON_LINE::UNIT_NUM
; Get ProDOS 8 block size (clears __oserror)
jsr _dio_query_sectsize
jsr _dio_query_sectsize
; Alloc buffer
jsr _malloc
sta ptr4
stx ptr4+1
jsr _malloc
sta ptr4
stx ptr4+1
; Set buffer
sta mliparam + MLI::ON_LINE::DATA_BUFFER
stx mliparam + MLI::ON_LINE::DATA_BUFFER+1
sta mliparam + MLI::ON_LINE::DATA_BUFFER
stx mliparam + MLI::ON_LINE::DATA_BUFFER+1
; Check buffer (hibyte is enough)
txa
beq nomem
beq nomem
; Get device state
lda #ON_LINE_CALL
ldx #ON_LINE_COUNT
jsr callmli
bcs check
lda #ON_LINE_CALL
ldx #ON_LINE_COUNT
jsr callmli
bcs check
; UNIT_NUM already set
.assert MLI::RW_BLOCK::UNIT_NUM = MLI::ON_LINE::UNIT_NUM, error
@@ -45,27 +45,27 @@ _dio_query_sectcount:
.assert MLI::RW_BLOCK::DATA_BUFFER = MLI::ON_LINE::DATA_BUFFER, error
; Read volume directory key block
tax ; A = 0
lda #$02
sta mliparam + MLI::RW_BLOCK::BLOCK_NUM
stx mliparam + MLI::RW_BLOCK::BLOCK_NUM+1
lda #READ_BLOCK_CALL
ldx #RW_BLOCK_COUNT
jsr callmli
bcs oserr
tax ; A = 0
lda #$02
sta mliparam + MLI::RW_BLOCK::BLOCK_NUM
stx mliparam + MLI::RW_BLOCK::BLOCK_NUM+1
lda #READ_BLOCK_CALL
ldx #RW_BLOCK_COUNT
jsr callmli
bcs oserr
; Get and save total blocks from volume directory header
ldy #$29
lda (ptr4),y
ldy #$29
lda (ptr4),y
pha
iny
lda (ptr4),y
lda (ptr4),y
pha
; Cleanup buffer
done: lda ptr4
ldx ptr4+1
jsr _free
done: lda ptr4
ldx ptr4+1
jsr _free
; Restore total blocks and return
pla
@@ -73,23 +73,23 @@ done: lda ptr4
pla
rts
nomem: lda #$FF ; Error code for sure not used by MLI
oserr: sta __oserror
nomem: lda #$FF ; Error code for sure not used by MLI
oserr: sta __oserror
; Save total blocks for failure
lda #$00
lda #$00
pha
pha
beq done ; Branch always
beq done ; Branch always
; Check for non-ProDOS disk
check: cmp #$52 ; "Not a ProDOS volume"
bne oserr
sta __oserror
check: cmp #$52 ; "Not a ProDOS volume"
bne oserr
sta __oserror
; Save total blocks for a 16-sector disk
lda #<280
lda #<280
pha
lda #>280
lda #>280
pha
bne done ; Branch always
bne done ; Branch always
+5 -5
View File
@@ -4,15 +4,15 @@
; unsigned __fastcall__ dio_query_sectsize (dhandle_t handle);
;
.export _dio_query_sectsize
.export _dio_query_sectsize
.include "errno.inc"
.include "errno.inc"
_dio_query_sectsize:
; Clear error
stx __oserror ; X = 0
stx __oserror ; X = 0
; Return ProDOS 8 block size
txa ; X = 0
ldx #>512
txa ; X = 0
ldx #>512
rts
+6 -6
View File
@@ -4,12 +4,12 @@
; unsigned char __fastcall__ dio_write (dhandle_t handle, unsigned sect_num, const void *buffer);
;
.export _dio_write
.import dioprolog, diocommon
.export _dio_write
.import dioprolog, diocommon
.include "mli.inc"
.include "mli.inc"
_dio_write:
jsr dioprolog
lda #WRITE_BLOCK_CALL
jmp diocommon
jsr dioprolog
lda #WRITE_BLOCK_CALL
jmp diocommon
+8 -8
View File
@@ -36,23 +36,23 @@
/*****************************************************************************/
/* Data */
/* Data */
/*****************************************************************************/
struct DIR {
int fd;
int fd;
unsigned char entry_length;
unsigned char entries_per_block;
unsigned char current_entry;
union {
unsigned char bytes[512];
struct {
unsigned prev_block;
unsigned next_block;
unsigned char entries[1];
} content;
unsigned char bytes[512];
struct {
unsigned prev_block;
unsigned next_block;
unsigned char entries[1];
} content;
} block;
};
+3 -3
View File
@@ -34,12 +34,12 @@
initdostype:
lda $BF00
cmp #$4C ; Is MLI present? (JMP opcode)
cmp #$4C ; Is MLI present? (JMP opcode)
bne done
lda KVERSION ; ProDOS 8 kernel version
lda KVERSION ; ProDOS 8 kernel version
cmp #$10
bcs :+
ora #$10 ; Make high nibble match major version
ora #$10 ; Make high nibble match major version
: sta __dos_type
done: rts
+127 -127
View File
@@ -5,48 +5,48 @@
; Ullrich von Bassewitz, 2002-12-02
;
.include "zeropage.inc"
.include "zeropage.inc"
.include "em-kernel.inc"
.include "em-error.inc"
.include "em-kernel.inc"
.include "em-error.inc"
; ------------------------------------------------------------------------
; Header. Includes jump table
.segment "JUMPTABLE"
.segment "JUMPTABLE"
; Driver signature
.byte $65, $6d, $64 ; "emd"
.byte EMD_API_VERSION ; EM API version number
.byte $65, $6d, $64 ; "emd"
.byte EMD_API_VERSION ; EM API version number
; Jump table.
.word INSTALL
.word DEINSTALL
.word PAGECOUNT
.word MAP
.word USE
.word COMMIT
.word COPYFROM
.word COPYTO
.word INSTALL
.word DEINSTALL
.word PAGECOUNT
.word MAP
.word USE
.word COMMIT
.word COPYFROM
.word COPYTO
; ------------------------------------------------------------------------
; Constants
BASE = $0200
AUXCARD = $C30C ; Card signature
AUXMOVE = $C311 ; Auxiliary move routine
PAGES = ($C000 - BASE) / 256
BASE = $0200
AUXCARD = $C30C ; Card signature
AUXMOVE = $C311 ; Auxiliary move routine
PAGES = ($C000 - BASE) / 256
; ------------------------------------------------------------------------
; Data.
.data
curpage: .byte $FF ; Current page number (invalid)
curpage: .byte $FF ; Current page number (invalid)
.bss
window: .res 256 ; Memory "window"
window: .res 256 ; Memory "window"
.code
@@ -58,15 +58,15 @@ window: .res 256 ; Memory "window"
;
INSTALL:
ldx #0
lda AUXCARD
and #$f0
cmp #$80
bne @L1
lda #EM_ERR_OK
rts
@L1: lda #EM_ERR_NO_DEVICE
; rts
ldx #0
lda AUXCARD
and #$f0
cmp #$80
bne @L1
lda #EM_ERR_OK
rts
@L1: lda #EM_ERR_NO_DEVICE
; rts
; ------------------------------------------------------------------------
; DEINSTALL routine. Is called before the driver is removed from memory.
@@ -74,7 +74,7 @@ INSTALL:
;
DEINSTALL:
rts
rts
; ------------------------------------------------------------------------
@@ -82,9 +82,9 @@ DEINSTALL:
;
PAGECOUNT:
lda #<PAGES
ldx #>PAGES
rts
lda #<PAGES
ldx #>PAGES
rts
; ------------------------------------------------------------------------
; MAP: Map the page in a/x into memory and return a pointer to the page in
@@ -92,83 +92,83 @@ PAGECOUNT:
; by the driver.
;
MAP: sta curpage ; Remember the new page
MAP: sta curpage ; Remember the new page
clc
adc #>BASE
sta ptr1+1
ldy #$00
sty ptr1
clc
adc #>BASE
sta ptr1+1
ldy #$00
sty ptr1
lda #<window
sta ptr2
lda #>window
sta ptr2+1
lda #<window
sta ptr2
lda #>window
sta ptr2+1
; Transfer one page
clc ; Direction flag
jsr transfer ; Transfer one page
clc ; Direction flag
jsr transfer ; Transfer one page
; Return the memory window
lda #<window
ldx #>window ; Return the window address
lda #<window
ldx #>window ; Return the window address
; Done
done: rts
done: rts
; ------------------------------------------------------------------------
; USE: Tell the driver that the window is now associated with a given page.
USE: sta curpage ; Remember the page
lda #<window
ldx #>window ; Return the window
rts
USE: sta curpage ; Remember the page
lda #<window
ldx #>window ; Return the window
rts
; ------------------------------------------------------------------------
; COMMIT: Commit changes in the memory window to extended storage.
COMMIT: lda curpage ; Get the current page
cmp #$FF
beq done ; Jump if no page mapped
COMMIT: lda curpage ; Get the current page
cmp #$FF
beq done ; Jump if no page mapped
clc
adc #>BASE
sta ptr2+1
ldy #$00
sty ptr2
clc
adc #>BASE
sta ptr2+1
ldy #$00
sty ptr2
lda #<window
sta ptr1
lda #>window
sta ptr1+1
lda #<$FF
sta ptr4
lda #>$FF
sta ptr4+1
sec ; Direction flag
lda #<window
sta ptr1
lda #>window
sta ptr1+1
lda #<$FF
sta ptr4
lda #>$FF
sta ptr4+1
sec ; Direction flag
; Transfer one page/all bytes
transfer:
php
clc
lda ptr1
sta $3C
adc ptr4
sta $3E
lda ptr1+1
sta $3D
adc ptr4+1
sta $3F
lda ptr2
sta $42
lda ptr2+1
sta $43
plp
jmp AUXMOVE
php
clc
lda ptr1
sta $3C
adc ptr4
sta $3E
lda ptr1+1
sta $3D
adc ptr4+1
sta $3F
lda ptr2
sta $42
lda ptr2+1
sta $43
plp
jmp AUXMOVE
; ------------------------------------------------------------------------
; COPYFROM: Copy from extended into linear memory. A pointer to a structure
@@ -177,34 +177,34 @@ transfer:
;
COPYFROM:
sta ptr3
stx ptr3+1 ; Save the passed em_copy pointer
sta ptr3
stx ptr3+1 ; Save the passed em_copy pointer
ldy #EM_COPY::OFFS
lda (ptr3),y
sta ptr1
ldy #EM_COPY::PAGE
lda (ptr3),y
clc
adc #>BASE
sta ptr1+1 ; From
ldy #EM_COPY::OFFS
lda (ptr3),y
sta ptr1
ldy #EM_COPY::PAGE
lda (ptr3),y
clc
adc #>BASE
sta ptr1+1 ; From
ldy #EM_COPY::BUF
lda (ptr3),y
sta ptr2
iny
lda (ptr3),y
sta ptr2+1 ; To
clc ; Direction flag
ldy #EM_COPY::BUF
lda (ptr3),y
sta ptr2
iny
lda (ptr3),y
sta ptr2+1 ; To
clc ; Direction flag
common: ldy #EM_COPY::COUNT
lda (ptr3),y ; Get bytes in last page
sta ptr4
iny
lda (ptr3),y ; Get number of pages
sta ptr4+1
common: ldy #EM_COPY::COUNT
lda (ptr3),y ; Get bytes in last page
sta ptr4
iny
lda (ptr3),y ; Get number of pages
sta ptr4+1
jmp transfer
jmp transfer
; ------------------------------------------------------------------------
; COPYTO: Copy from linear into extended memory. A pointer to a structure
@@ -212,24 +212,24 @@ common: ldy #EM_COPY::COUNT
; The function must not return anything.
;
COPYTO: sta ptr3
stx ptr3+1 ; Save the passed em_copy pointer
COPYTO: sta ptr3
stx ptr3+1 ; Save the passed em_copy pointer
ldy #EM_COPY::OFFS
lda (ptr3),y
sta ptr2
ldy #EM_COPY::PAGE
lda (ptr3),y
clc
adc #>BASE
sta ptr2+1 ; To
ldy #EM_COPY::OFFS
lda (ptr3),y
sta ptr2
ldy #EM_COPY::PAGE
lda (ptr3),y
clc
adc #>BASE
sta ptr2+1 ; To
ldy #EM_COPY::BUF
lda (ptr3),y
sta ptr1
iny
lda (ptr3),y
sta ptr1+1 ; From
ldy #EM_COPY::BUF
lda (ptr3),y
sta ptr1
iny
lda (ptr3),y
sta ptr1+1 ; From
sec ; Direction flag
jmp common
sec ; Direction flag
jmp common
+108 -108
View File
@@ -4,108 +4,108 @@
; int __fastcall__ exec (const char* progname, const char* cmdline);
;
.export _exec
.import pushname, popname
.import popax, done, _exit
.export _exec
.import pushname, popname
.import popax, done, _exit
.include "zeropage.inc"
.include "errno.inc"
.include "apple2.inc"
.include "mli.inc"
.include "zeropage.inc"
.include "errno.inc"
.include "apple2.inc"
.include "mli.inc"
; Wrong file type
typerr: lda #$4A ; "Incompatible file format"
typerr: lda #$4A ; "Incompatible file format"
; Cleanup name
oserr: jsr popname ; Preserves A
oserr: jsr popname ; Preserves A
; Set __oserror
jmp __mappederrno
jmp __mappederrno
_exec:
; Get and push name
jsr popax
jsr pushname
bne oserr
jsr popax
jsr pushname
bne oserr
; Set pushed name
lda sp
ldx sp+1
sta mliparam + MLI::INFO::PATHNAME
stx mliparam + MLI::INFO::PATHNAME+1
lda sp
ldx sp+1
sta mliparam + MLI::INFO::PATHNAME
stx mliparam + MLI::INFO::PATHNAME+1
; Get file_type and aux_type
lda #GET_INFO_CALL
ldx #GET_INFO_COUNT
jsr callmli
bcs oserr
lda #GET_INFO_CALL
ldx #GET_INFO_COUNT
jsr callmli
bcs oserr
; If we get here the program file at least exists so we copy
; the loader stub right now and patch it later to set params
ldx #size - 1
: lda source,x
sta target,x
ldx #size - 1
: lda source,x
sta target,x
dex
bpl :-
bpl :-
; Check program file type
lda mliparam + MLI::INFO::FILE_TYPE
cmp #$FF ; SYS file?
bne binary ; No, check for BIN file
lda mliparam + MLI::INFO::FILE_TYPE
cmp #$FF ; SYS file?
bne binary ; No, check for BIN file
; ProDOS TechRefMan, chapter 5.1.5.1:
; "The complete or partial pathname of the system program
; is stored at $280, starting with a length byte."
ldy #$00
lda (sp),y
ldy #$00
lda (sp),y
tay
: lda (sp),y
sta $0280,y
: lda (sp),y
sta $0280,y
dey
bpl :-
bpl :-
; SYS programs replace BASIC.SYSTEM so set in the ProDOS system bit map
; protection for pages $80 - $BF just in case BASIC.SYSTEM is there now
ldx #$0F ; Start with protection for pages $B8 - $BF
lda #%00000001 ; Protect only system global page
: sta $BF60,x ; Set protection for 8 pages
lda #$00 ; Protect no page
ldx #$0F ; Start with protection for pages $B8 - $BF
lda #%00000001 ; Protect only system global page
: sta $BF60,x ; Set protection for 8 pages
lda #$00 ; Protect no page
dex
bpl :-
bmi prodos ; Branch always
bpl :-
bmi prodos ; Branch always
binary: cmp #$06 ; BIN file?
bne typerr ; No, wrong file type
binary: cmp #$06 ; BIN file?
bne typerr ; No, wrong file type
; Set BIN program load addr
lda mliparam + MLI::INFO::AUX_TYPE
ldx mliparam + MLI::INFO::AUX_TYPE+1
sta data_buffer
stx data_buffer+1
lda mliparam + MLI::INFO::AUX_TYPE
ldx mliparam + MLI::INFO::AUX_TYPE+1
sta data_buffer
stx data_buffer+1
; Check ProDOS system bit map for presence of BASIC.SYSTEM
lda $BF6F ; Protection for pages $B8 - $BF
cmp #%00000001 ; Exactly system global page is protected
beq setvec
lda $BF6F ; Protection for pages $B8 - $BF
cmp #%00000001 ; Exactly system global page is protected
beq setvec
; Get highest available mem addr from BASIC.SYSTEM
ldx HIMEM+1 ; High byte
bne setbuf ; Branch always
ldx HIMEM+1 ; High byte
bne setbuf ; Branch always
; BIN programs are supposed to quit through one of the two DOS
; vectors so we set up those to point to the ProDOS dispatcher
setvec: ldx #$03 - 1 ; Size of JMP opcode
: lda dosvec,x
sta DOSWARM,x ; DOS warm start
sta DOSWARM + 3,x ; DOS cold start
setvec: ldx #$03 - 1 ; Size of JMP opcode
: lda dosvec,x
sta DOSWARM,x ; DOS warm start
sta DOSWARM + 3,x ; DOS cold start
dex
bpl :-
bpl :-
; No BASIC.SYSTEM so use addr of ProDOS system global page
prodos: ldx #>$BF00 ; High byte
prodos: ldx #>$BF00 ; High byte
; The I/O buffer needs to be page aligned
setbuf: lda #$00 ; Low byte
setbuf: lda #$00 ; Low byte
; The I/O buffer needs four pages
dex
@@ -114,109 +114,109 @@ setbuf: lda #$00 ; Low byte
dex
; Set I/O buffer
sta mliparam + MLI::OPEN::IO_BUFFER
stx mliparam + MLI::OPEN::IO_BUFFER+1
sta mliparam + MLI::OPEN::IO_BUFFER
stx mliparam + MLI::OPEN::IO_BUFFER+1
; PATHNAME already set
.assert MLI::OPEN::PATHNAME = MLI::INFO::PATHNAME, error
; Lower file level to avoid program file
; being closed by C libary shutdown code
ldx LEVEL
stx level
beq :+
dec LEVEL
ldx LEVEL
stx level
beq :+
dec LEVEL
; Open file
: lda #OPEN_CALL
ldx #OPEN_COUNT
jsr callmli
: lda #OPEN_CALL
ldx #OPEN_COUNT
jsr callmli
; Restore file level
ldx level
stx LEVEL
bcc :+
jmp oserr
ldx level
stx LEVEL
bcc :+
jmp oserr
; Get and save fd
: lda mliparam + MLI::OPEN::REF_NUM
sta read_ref
sta close_ref
: lda mliparam + MLI::OPEN::REF_NUM
sta read_ref
sta close_ref
.ifdef __APPLE2ENH__
; Calling the 80 column firmware needs the ROM switched
; in, otherwise it copies the F8 ROM to the LC (@ $CEF4)
bit $C082
bit $C082
; ProDOS TechRefMan, chapter 5.3.1.3:
; "80-column text cards -- and other Apple IIe features -- can
; be turned off using the following sequence of instructions:"
lda #$15
jsr $C300
lda #$15
jsr $C300
; Switch in LC bank 2 for R/O
bit $C080
bit $C080
.endif
; Call loader stub after C libary shutdown
lda #<target
ldx #>target
sta done
stx done+1
lda #<target
ldx #>target
sta done
stx done+1
; Initiate C libary shutdown
jmp _exit
jmp _exit
.bss
level : .res 1
level : .res 1
.rodata
; Read whole program file
source: jsr $BF00
.byte READ_CALL
.word read_param
bcs :+
source: jsr $BF00
.byte READ_CALL
.word read_param
bcs :+
; Close program file
jsr $BF00
.byte CLOSE_CALL
.word close_param
bcs :+
jsr $BF00
.byte CLOSE_CALL
.word close_param
bcs :+
; Go for it ...
jmp (data_buffer)
jmp (data_buffer)
read_param = * - source + target
.byte $04 ; PARAM_COUNT
.byte $04 ; PARAM_COUNT
read_ref = * - source + target
.byte $00 ; REF_NUM
.byte $00 ; REF_NUM
data_buffer = * - source + target
.addr $2000 ; DATA_BUFFER
.word $FFFF ; REQUEST_COUNT
.word $0000 ; TRANS_COUNT
.addr $2000 ; DATA_BUFFER
.word $FFFF ; REQUEST_COUNT
.word $0000 ; TRANS_COUNT
close_param = * - source + target
.byte $01 ; PARAM_COUNT
.byte $01 ; PARAM_COUNT
close_ref = * - source + target
.byte $00 ; REF_NUM
.byte $00 ; REF_NUM
; Quit to ProDOS dispatcher
quit = * - source + target
: jsr $BF00
.byte $65 ; QUIT
.word quit_param
: jsr $BF00
.byte $65 ; QUIT
.word quit_param
quit_param = * - source + target
.byte $04 ; PARAM_COUNT
.byte $00 ; QUIT_TYPE
.word $0000 ; RESERVED
.byte $00 ; RESERVED
.word $0000 ; RESERVED
.byte $04 ; PARAM_COUNT
.byte $00 ; QUIT_TYPE
.word $0000 ; RESERVED
.byte $00 ; RESERVED
.word $0000 ; RESERVED
size = * - source
target = DOSWARM - size
dosvec: jmp quit
dosvec: jmp quit
+4 -4
View File
@@ -5,12 +5,12 @@
; containing the load address and load length.
;
.export __EXEHDR__ : absolute = 1 ; Linker referenced
.import __LOADADDR__, __LOADSIZE__ ; Linker generated
.export __EXEHDR__ : absolute = 1 ; Linker referenced
.import __LOADADDR__, __LOADSIZE__ ; Linker generated
; ------------------------------------------------------------------------
.segment "EXEHDR"
.addr __LOADADDR__ ; Load address
.word __LOADSIZE__ ; Load length
.addr __LOADADDR__ ; Load address
.word __LOADSIZE__ ; Load length
+18 -18
View File
@@ -5,16 +5,16 @@
; location $0800 and the cc65 program start address
;
.constructor initiobuf
.export iobuf_alloc, iobuf_free
.import __STARTUP_RUN__
.import incsp2, popax
.constructor initiobuf
.export iobuf_alloc, iobuf_free
.import __STARTUP_RUN__
.import incsp2, popax
.include "zeropage.inc"
.include "errno.inc"
.include "../filedes.inc"
.include "zeropage.inc"
.include "errno.inc"
.include "../filedes.inc"
.segment "INIT"
.segment "INIT"
initiobuf:
; Convert end address highbyte to table index
@@ -40,10 +40,10 @@ initiobuf:
iobuf_alloc:
; Get and save "memptr"
jsr incsp2
jsr popax
sta ptr1
stx ptr1+1
jsr incsp2
jsr popax
sta ptr1
stx ptr1+1
; Search table for free entry
ldx #$00
@@ -67,11 +67,11 @@ iobuf_alloc:
adc #>$0800
; Store address in "memptr"
ldy #$01
sta (ptr1),y
dey
tya
sta (ptr1),y
ldy #$01
sta (ptr1),y
dey
tya
sta (ptr1),y
rts
iobuf_free:
@@ -86,7 +86,7 @@ iobuf_free:
tax
lda #$00
sta table,x
rts
rts
; ------------------------------------------------------------------------
+20 -20
View File
@@ -4,18 +4,18 @@
; File descriptor management for the POSIX I/O routines
;
.include "errno.inc"
.include "fcntl.inc"
.include "filedes.inc"
.include "errno.inc"
.include "fcntl.inc"
.include "filedes.inc"
getfd:
; Check for handle >= 256
cpx #$00
bne error
cpx #$00
bne error
; Check for handle >= MAX_FDS
cmp #MAX_FDS
bcs error
cmp #MAX_FDS
bcs error
; Convert handle to fdtab slot
.assert .sizeof(FD) = 4, error
@@ -24,15 +24,15 @@ getfd:
; Check for fdtab slot in use
tay
lda fdtab + FD::REF_NUM,y
beq error
lda fdtab + FD::REF_NUM,y
beq error
; Return success
clc
rts
; Load errno code and return error
error: lda #EINVAL
error: lda #EINVAL
sec
rts
@@ -40,16 +40,16 @@ error: lda #EINVAL
fdtab: .assert .sizeof(FD) = 4, error
.byte $80 ; STDIN_FILENO ::REF_NUM
.byte O_RDONLY ; STDIN_FILENO ::FLAGS
.addr $0000 ; STDIN_FILENO ::BUFFER
.byte $80 ; STDIN_FILENO ::REF_NUM
.byte O_RDONLY ; STDIN_FILENO ::FLAGS
.addr $0000 ; STDIN_FILENO ::BUFFER
.byte $80 ; STDOUT_FILENO::REF_NUM
.byte O_WRONLY ; STDOUT_FILENO::FLAGS
.addr $0000 ; STDOUT_FILENO::BUFFER
.byte $80 ; STDOUT_FILENO::REF_NUM
.byte O_WRONLY ; STDOUT_FILENO::FLAGS
.addr $0000 ; STDOUT_FILENO::BUFFER
.byte $80 ; STDERR_FILENO::REF_NUM
.byte O_WRONLY ; STDERR_FILENO::FLAGS
.addr $0000 ; STDERR_FILENO::BUFFER
.byte $80 ; STDERR_FILENO::REF_NUM
.byte O_WRONLY ; STDERR_FILENO::FLAGS
.addr $0000 ; STDERR_FILENO::BUFFER
.res (MAX_FDS - 3) * .sizeof(FD)
.res (MAX_FDS - 3) * .sizeof(FD)
+51 -51
View File
@@ -4,88 +4,88 @@
; File name handling for ProDOS 8 file I/O
;
.export pushname, popname
.import subysp, addysp, decsp1
.export pushname, popname
.import subysp, addysp, decsp1
.include "zeropage.inc"
.include "mli.inc"
.include "zeropage.inc"
.include "mli.inc"
pushname:
sta ptr1
stx ptr1+1
sta ptr1
stx ptr1+1
; Alloc pathname buffer
ldy #64+1 ; Max pathname length + zero
jsr subysp
ldy #64+1 ; Max pathname length + zero
jsr subysp
; Check for full pathname
ldy #$00
lda (ptr1),y
cmp #'/'
beq copy
ldy #$00
lda (ptr1),y
cmp #'/'
beq copy
; Check for system prefix
lda PFIXPTR
bne copy
lda PFIXPTR
bne copy
; Use unit number of most recent accessed device
lda DEVNUM
sta mliparam + MLI::ON_LINE::UNIT_NUM
lda DEVNUM
sta mliparam + MLI::ON_LINE::UNIT_NUM
; Use allocated pathname buffer
lda sp
ldx sp+1
sta mliparam + MLI::ON_LINE::DATA_BUFFER
stx mliparam + MLI::ON_LINE::DATA_BUFFER+1
lda sp
ldx sp+1
sta mliparam + MLI::ON_LINE::DATA_BUFFER
stx mliparam + MLI::ON_LINE::DATA_BUFFER+1
; Get volume name
lda #ON_LINE_CALL
ldx #ON_LINE_COUNT
jsr callmli
bcs addsp65
lda #ON_LINE_CALL
ldx #ON_LINE_COUNT
jsr callmli
bcs addsp65
; Get volume name length
lda (sp),y
and #15 ; Max volume name length
lda (sp),y
and #15 ; Max volume name length
; Bracket volume name with slashes to form prefix
sta tmp1
lda #'/'
sta (sp),y
ldy tmp1
iny ; Leading slash
sta (sp),y
iny ; Trailing slash
sta tmp1
lda #'/'
sta (sp),y
ldy tmp1
iny ; Leading slash
sta (sp),y
iny ; Trailing slash
; Adjust source pointer for copy
sty tmp1
lda ptr1
sty tmp1
lda ptr1
sec
sbc tmp1
bcs :+
dec ptr1+1
: sta ptr1
sbc tmp1
bcs :+
dec ptr1+1
: sta ptr1
; Copy source to allocated pathname buffer
copy: lda (ptr1),y
sta (sp),y
beq setlen
copy: lda (ptr1),y
sta (sp),y
beq setlen
iny
cpy #64+1 ; Max pathname length + zero
bcc copy
cpy #64+1 ; Max pathname length + zero
bcc copy
; Load oserror code
lda #$40 ; "Invalid pathname"
lda #$40 ; "Invalid pathname"
; Free pathname buffer
addsp65:ldy #64+1
bne addsp ; Branch always
bne addsp ; Branch always
; Alloc and set length byte
setlen: tya
jsr decsp1 ; Preserves A
ldy #$00
sta (sp),y
jsr decsp1 ; Preserves A
ldy #$00
sta (sp),y
; Return success
tya
@@ -93,5 +93,5 @@ setlen: tya
popname:
; Cleanup stack
ldy #1 + 64+1 ; Length byte + max pathname length + zero
addsp: jmp addysp ; Preserves A
ldy #1 + 64+1 ; Length byte + max pathname length + zero
addsp: jmp addysp ; Preserves A
+24 -24
View File
@@ -24,38 +24,38 @@ nogs: ldx #$FF
next: inx
lda value,x
ldy index,x
beq done ; $00 is no valid index
beq done ; $00 is no valid index
cmp $FB00,y
beq next
: inx
ldy index,x
bne :-
beq next ; Branch always
beq next ; Branch always
index: .byte $B3, $00 ; Apple ][
.byte $B3, $1E, $00 ; Apple ][+
.byte $B3, $1E, $00 ; Apple /// (emulation)
.byte $B3, $C0, $00 ; Apple //e
.byte $B3, $C0, $DD, $BE, $00 ; Apple //e Option Card
.byte $B3, $C0, $00 ; Apple //e (enhanced)
.byte $B3, $C0, $BF, $00 ; Apple //c
.byte $B3, $C0, $BF, $00 ; Apple //c (3.5 ROM)
.byte $B3, $C0, $BF, $00 ; Apple //c (Mem. Exp.)
.byte $B3, $C0, $BF, $00 ; Apple //c (Rev. Mem. Exp.)
.byte $B3, $C0, $BF, $00 ; Apple //c Plus
index: .byte $B3, $00 ; Apple ][
.byte $B3, $1E, $00 ; Apple ][+
.byte $B3, $1E, $00 ; Apple /// (emulation)
.byte $B3, $C0, $00 ; Apple //e
.byte $B3, $C0, $DD, $BE, $00 ; Apple //e Option Card
.byte $B3, $C0, $00 ; Apple //e (enhanced)
.byte $B3, $C0, $BF, $00 ; Apple //c
.byte $B3, $C0, $BF, $00 ; Apple //c (3.5 ROM)
.byte $B3, $C0, $BF, $00 ; Apple //c (Mem. Exp.)
.byte $B3, $C0, $BF, $00 ; Apple //c (Rev. Mem. Exp.)
.byte $B3, $C0, $BF, $00 ; Apple //c Plus
.byte $00
value: .byte $38, $10 ; Apple ][
.byte $EA, $AD, $11 ; Apple ][+
.byte $EA, $8A, $20 ; Apple /// (emulation)
.byte $06, $EA, $30 ; Apple //e
.byte $06, $E0, $02, $00, $40 ; Apple //e Option Card
.byte $06, $E0, $31 ; Apple //e (enhanced)
.byte $06, $00, $FF, $50 ; Apple //c
.byte $06, $00, $00, $51 ; Apple //c (3.5 ROM)
.byte $06, $00, $03, $53 ; Apple //c (Mem. Exp.)
.byte $06, $00, $04, $54 ; Apple //c (Rev. Mem. Exp.)
.byte $06, $00, $05, $55 ; Apple //c Plus
value: .byte $38, $10 ; Apple ][
.byte $EA, $AD, $11 ; Apple ][+
.byte $EA, $8A, $20 ; Apple /// (emulation)
.byte $06, $EA, $30 ; Apple //e
.byte $06, $E0, $02, $00, $40 ; Apple //e Option Card
.byte $06, $E0, $31 ; Apple //e (enhanced)
.byte $06, $00, $FF, $50 ; Apple //c
.byte $06, $00, $00, $51 ; Apple //c (3.5 ROM)
.byte $06, $00, $03, $53 ; Apple //c (Mem. Exp.)
.byte $06, $00, $04, $54 ; Apple //c (Rev. Mem. Exp.)
.byte $06, $00, $05, $55 ; Apple //c Plus
.byte $00
.code
+3 -3
View File
@@ -13,10 +13,10 @@
_gotoxy:
clc
adc WNDTOP
sta CV ; Store Y
sta CV ; Store Y
jsr VTABZ
jsr popa ; Get X
jsr popa ; Get X
_gotox:
sta CH ; Store X
sta CH ; Store X
rts
+1 -1
View File
@@ -12,7 +12,7 @@
_gotoy:
clc
adc WNDTOP
sta CV ; Store Y
sta CV ; Store Y
jmp VTABZ
+9 -9
View File
@@ -4,17 +4,17 @@
; HOME routine
;
.export HOME
.export HOME
.include "apple2.inc"
.include "apple2.inc"
.segment "LOWCODE"
.segment "LOWCODE"
HOME:
; Switch in ROM and call HOME
bit $C082
jsr $FC58 ; Clear current text screen
; Switch in ROM and call HOME
bit $C082
jsr $FC58 ; Clear current text screen
; Switch in LC bank 2 for R/O and return
bit $C080
rts
; Switch in LC bank 2 for R/O and return
bit $C080
rts
+19 -19
View File
@@ -3,15 +3,15 @@
;
.export initcwd
.import __cwd
.import __cwd
.include "zeropage.inc"
.include "zeropage.inc"
.include "mli.inc"
initcwd:
; Set static prefix buffer
lda #<__cwd
ldx #>__cwd
lda #<__cwd
ldx #>__cwd
sta mliparam + MLI::PREFIX::PATHNAME
stx mliparam + MLI::PREFIX::PATHNAME+1
@@ -21,20 +21,20 @@ initcwd:
jsr callmli
; Check for null prefix
lda __cwd
beq done
lda __cwd
beq done
; Remove length byte and trailing slash
sta tmp1
ldx #$01
: lda __cwd,x
sta __cwd - 1,x
inx
cpx tmp1
bcc :-
; Remove length byte and trailing slash
sta tmp1
ldx #$01
: lda __cwd,x
sta __cwd - 1,x
inx
cpx tmp1
bcc :-
; Add terminating zero
lda #$00
sta __cwd - 1,x
done: rts
; Add terminating zero
lda #$00
sta __cwd - 1,x
done: rts
+2 -2
View File
@@ -4,8 +4,8 @@
; Default ProDOS 8 I/O buffer management
;
.export iobuf_alloc, iobuf_free
.import _posix_memalign, _free
.export iobuf_alloc, iobuf_free
.import _posix_memalign, _free
iobuf_alloc := _posix_memalign
iobuf_free := _free
+36 -36
View File
@@ -7,9 +7,9 @@
; Using the readjoy code from Stefan Haubenthal
;
.include "zeropage.inc"
.include "zeropage.inc"
.include "joy-kernel.inc"
.include "joy-kernel.inc"
.include "joy-error.inc"
.include "apple2.inc"
@@ -17,24 +17,24 @@
; Constants
THRESHOLD = 20 ; Deviation from center triggering movement
THRESHOLD = 20 ; Deviation from center triggering movement
; ------------------------------------------------------------------------
; ROM entry points
PREAD := $FB1E ; Read paddle in X, return AD conv. value in Y
PREAD := $FB1E ; Read paddle in X, return AD conv. value in Y
; ------------------------------------------------------------------------
; Header. Includes jump table.
.segment "JUMPTABLE"
.segment "JUMPTABLE"
; Driver signature
.byte $6A, $6F, $79 ; "joy"
.byte JOY_API_VERSION ; Driver API version number
.byte $6A, $6F, $79 ; "joy"
.byte JOY_API_VERSION ; Driver API version number
; Button state masks (8 values)
@@ -57,7 +57,7 @@ PREAD := $FB1E ; Read paddle in X, return AD conv. value in Y
; ------------------------------------------------------------------------
.code
.code
; INSTALL routine. Is called after the driver is loaded into memory. If
; possible, check if the hardware is present and determine the amount of
@@ -66,7 +66,7 @@ PREAD := $FB1E ; Read paddle in X, return AD conv. value in Y
INSTALL:
lda #<JOY_ERR_OK
ldx #>JOY_ERR_OK
; Fall through
; Fall through
; UNINSTALL routine. Is called before the driver is removed from memory.
; Can do cleanup or whatever. Must not return anything.
@@ -75,55 +75,55 @@ UNINSTALL:
; COUNT: Return the total number of available joysticks in a/x.
COUNT:
lda #$02 ; Number of joysticks we support
lda #$02 ; Number of joysticks we support
ldx #$00
rts
; READ: Read a particular joystick passed in A.
READJOY:
bit $C082 ; Switch in ROM
and #$01 ; Restrict joystick number
bit $C082 ; Switch in ROM
and #$01 ; Restrict joystick number
; Read horizontal paddle
asl ; Joystick number -> paddle number
tax ; Set paddle number (0, 2)
; Read horizontal paddle
asl ; Joystick number -> paddle number
tax ; Set paddle number (0, 2)
jsr PREAD ; Read paddle value
lda #$00 ; 0 0 0 0 0 0 0 0
lda #$00 ; 0 0 0 0 0 0 0 0
cpy #127 - THRESHOLD
ror ; !LEFT 0 0 0 0 0 0 0
ror ; !LEFT 0 0 0 0 0 0 0
cpy #127 + THRESHOLD
ror ; RIGHT !LEFT 0 0 0 0 0 0
ror ; RIGHT !LEFT 0 0 0 0 0 0
; Read vertical paddle
; Read vertical paddle
pha
inx ; Set paddle number (1, 3)
inx ; Set paddle number (1, 3)
jsr PREAD ; Read paddle value
pla
cpy #127 - THRESHOLD
ror ; !UP RIGHT !LEFT 0 0 0 0 0
ror ; !UP RIGHT !LEFT 0 0 0 0 0
cpy #127 + THRESHOLD
ror ; DOWN !UP RIGHT !LEFT 0 0 0 0
ror ; DOWN !UP RIGHT !LEFT 0 0 0 0
; Read primary button
tay
lda BUTN0-1,x ; Check button (1, 3)
; Read primary button
tay
lda BUTN0-1,x ; Check button (1, 3)
asl
tya
ror ; FIRE DOWN !UP RIGHT !LEFT 0 0 0
ror ; FIRE DOWN !UP RIGHT !LEFT 0 0 0
; Read secondary button
tay
inx
txa
and #$03 ; IIgs has fourth button at TAPEIN
tax
lda BUTN0-1,x ; Check button (2, 0)
; Read secondary button
tay
inx
txa
and #$03 ; IIgs has fourth button at TAPEIN
tax
lda BUTN0-1,x ; Check button (2, 0)
asl
tya
ror ; FIRE2 FIRE DOWN !UP RIGHT !LEFT 0 0
ror ; FIRE2 FIRE DOWN !UP RIGHT !LEFT 0 0
; Finalize
; Finalize
eor #%00010100 ; FIRE2 FIRE DOWN UP RIGHT LEFT 0 0
ldx #$00
bit $C080 ; Switch in LC bank 2 for R/O
bit $C080 ; Switch in LC bank 2 for R/O
rts
+5 -5
View File
@@ -6,16 +6,16 @@
; const void joy_static_stddrv[];
;
.export _joy_static_stddrv
.ifdef __APPLE2ENH__
.import _a2e_stdjoy_joy
.export _joy_static_stddrv
.ifdef __APPLE2ENH__
.import _a2e_stdjoy_joy
.else
.import _a2_stdjoy_joy
.import _a2_stdjoy_joy
.endif
.rodata
.ifdef __APPLE2ENH__
.ifdef __APPLE2ENH__
_joy_static_stddrv := _a2e_stdjoy_joy
.else
_joy_static_stddrv := _a2_stdjoy_joy
+4 -4
View File
@@ -6,14 +6,14 @@
; const char joy_stddrv[];
;
.export _joy_stddrv
.export _joy_stddrv
.rodata
_joy_stddrv:
.ifdef __APPLE2ENH__
.asciiz "A2E.STDJOY.JOY"
.ifdef __APPLE2ENH__
.asciiz "A2E.STDJOY.JOY"
.else
.asciiz "A2.STDJOY.JOY"
.asciiz "A2.STDJOY.JOY"
.endif
+58 -58
View File
@@ -22,11 +22,11 @@
; TO-DO:
; Add a control-character quoting mechanism.
.constructor initmainargs, 24
.import __argc, __argv, __dos_type
.constructor initmainargs, 24
.import __argc, __argv, __dos_type
.include "zeropage.inc"
.include "apple2.inc"
.include "zeropage.inc"
.include "apple2.inc"
; Maximum number of arguments allowed in the argument table.
; (An argument contains a comma, at least.)
@@ -44,7 +44,7 @@ BUF_LEN = 122
BASIC_BUF = $200
FNAM_LEN = $280
FNAM = $281
REM = $B2 ; BASIC token-code
REM = $B2 ; BASIC token-code
; Get possible command-line arguments. Goes into the special INIT segment,
; which may be reused after the startup code is run.
@@ -56,25 +56,25 @@ initmainargs:
; Assume that the program was loaded, a moment ago, by the traditional BLOAD
; statement of BASIC.SYSTEM. Save the filename as argument #0 if available.
ldx __dos_type ; No ProDOS -> argv[0] = ""
beq :+
ldx __dos_type ; No ProDOS -> argv[0] = ""
beq :+
; Terminate the filename with a zero to make it a valid C string.
ldx FNAM_LEN
: lda #$00
sta FNAM,x
ldx FNAM_LEN
: lda #$00
sta FNAM,x
inc __argc ; argc always is equal to, at least, 1
inc __argc ; argc always is equal to, at least, 1
; Find the "rem" token.
ldx #$00
: lda BASIC_BUF,x
beq done ; No "rem" -> no args
ldx #$00
: lda BASIC_BUF,x
beq done ; No "rem" -> no args
inx
cmp #REM
bne :-
cmp #REM
bne :-
; If a clock is present it is called by ProDOS on file operations. On machines
; with a slot-based clock (like the Thunder Clock) the clock firmware places
@@ -82,18 +82,18 @@ initmainargs:
; of the command-line in a different buffer before the original is potentially
; destroyed.
ldy #$00
: lda BASIC_BUF,x
sta buffer,y
inx
iny
cpy #BUF_LEN - 1 ; Keep the terminating zero intact
bcc :-
ldy #$00
: lda BASIC_BUF,x
sta buffer,y
inx
iny
cpy #BUF_LEN - 1 ; Keep the terminating zero intact
bcc :-
; Start processing the arguments.
ldx #$00
ldy #$01 * 2 ; Start with argv[1]
ldx #$00
ldy #$01 * 2 ; Start with argv[1]
; Find the next argument. Stop if the end of the string or a character with the
; hibit set is reached. The later is true if the string isn't already parsed by
@@ -105,65 +105,65 @@ initmainargs:
; for the REM token we stumbled across the first '2' character ($32+$80 = $B2)
; and interpreted the rest of the date as a spurious command-line parameter.
next: lda buffer,x
beq done
bmi done
next: lda buffer,x
beq done
bmi done
inx
cmp #' ' ; Skip leading spaces
beq next
cmp #' ' ; Skip leading spaces
beq next
; Found start of next argument. We've incremented the pointer in X already, so
; it points to the second character of the argument. This is useful since we
; will check now for a quoted argument, in which case we will have to skip this
; first character.
cmp #'"' ; Is the argument quoted?
beq :+ ; Jump if so
dex ; Reset pointer to first argument character
lda #' ' ; A space ends the argument
: sta tmp1 ; Set end of argument marker
cmp #'"' ; Is the argument quoted?
beq :+ ; Jump if so
dex ; Reset pointer to first argument character
lda #' ' ; A space ends the argument
: sta tmp1 ; Set end of argument marker
; Now store a pointer to the argument into the next slot.
txa ; Get low byte
txa ; Get low byte
clc
adc #<buffer
sta argv,y ; argv[y] = &arg
adc #<buffer
sta argv,y ; argv[y] = &arg
iny
lda #$00
adc #>buffer
sta argv,y
lda #$00
adc #>buffer
sta argv,y
iny
inc __argc ; Found another arg
inc __argc ; Found another arg
; Search for the end of the argument.
: lda buffer,x
beq done
beq done
inx
cmp tmp1
bne :-
cmp tmp1
bne :-
; We've found the end of the argument. X points one character behind it, and
; A contains the terminating character. To make the argument a valid C string,
; replace the terminating character by a zero.
lda #$00
sta buffer-1,x
lda #$00
sta buffer-1,x
; Check if the maximum number of command-line arguments is reached. If not,
; parse the next one.
lda __argc ; Get low byte of argument count
cmp #MAXARGS ; Maximum number of arguments reached?
bcc next ; Parse next one if not
lda __argc ; Get low byte of argument count
cmp #MAXARGS ; Maximum number of arguments reached?
bcc next ; Parse next one if not
; (The last vector in argv[] already is NULL.)
done: lda #<argv
ldx #>argv
sta __argv
stx __argv+1
done: lda #<argv
ldx #>argv
sta __argv
stx __argv+1
rts
; This array is zeroed before initmainargs is called.
@@ -171,9 +171,9 @@ done: lda #<argv
.data
argv: .addr FNAM
.res MAXARGS * 2
argv: .addr FNAM
.res MAXARGS * 2
.bss
.bss
buffer: .res BUF_LEN
buffer: .res BUF_LEN
+74 -74
View File
@@ -1,38 +1,38 @@
;
; Default mouse callbacks for the Apple II
; Default mouse callbacks for the Apple II
;
; Oliver Schmidt, 22.09.2005
;
; All functions in this module should be interrupt safe, because they may
; All functions in this module should be interrupt safe, because they may
; be called from an interrupt handler
;
.export _mouse_def_callbacks
.include "apple2.inc"
.export _mouse_def_callbacks
.include "apple2.inc"
; ------------------------------------------------------------------------
.bss
backup: .res 1
.bss
backup: .res 1
; ------------------------------------------------------------------------
.rodata
.rodata
; Callback structure
; Callback structure
_mouse_def_callbacks:
.addr hide
.addr show
.addr movex
.addr movey
.addr hide
.addr show
.addr movex
.addr movey
; ------------------------------------------------------------------------
.data
.data
.ifdef __APPLE2ENH__
.ifdef __APPLE2ENH__
cursor = 'B' ; MouseText character
.else
cursor = '+' | $40 ; Flashing crosshair
@@ -41,85 +41,85 @@ cursor = '+' | $40 ; Flashing crosshair
getcursor:
.ifdef __APPLE2ENH__
bit RD80VID ; In 80 column mode?
bpl column ; No, skip bank switching
switch: bit LOWSCR ; Patched at runtime
bpl column ; No, skip bank switching
switch: bit LOWSCR ; Patched at runtime
.endif
column: ldx #$00 ; Patched at runtime
getscr: lda $0400,x ; Patched at runtime
cmp #cursor
rts
column: ldx #$00 ; Patched at runtime
getscr: lda $0400,x ; Patched at runtime
cmp #cursor
rts
setcursor:
lda #cursor
setscr: sta $0400,x ; Patched at runtime
.ifdef __APPLE2ENH__
bit LOWSCR ; Doesn't hurt in 40 column mode
lda #cursor
setscr: sta $0400,x ; Patched at runtime
.ifdef __APPLE2ENH__
bit LOWSCR ; Doesn't hurt in 40 column mode
.endif
rts
rts
; ------------------------------------------------------------------------
.code
.code
done:
.ifdef __APPLE2ENH__
bit LOWSCR ; Doesn't hurt in 40 column mode
.ifdef __APPLE2ENH__
bit LOWSCR ; Doesn't hurt in 40 column mode
.endif
rts
rts
; Hide the mouse cursor.
hide:
jsr getcursor ; Cursor visible at current position?
bne done ; No, we're done
lda backup ; Get character at cursor position
jmp setscr ; Draw character
jsr getcursor ; Cursor visible at current position?
bne done ; No, we're done
lda backup ; Get character at cursor position
jmp setscr ; Draw character
; Show the mouse cursor.
show:
jsr getcursor ; Cursor visible at current position?
beq done ; Yes, we're done
sta backup ; Save character at cursor position
jmp setcursor ; Draw cursor
jsr getcursor ; Cursor visible at current position?
beq done ; Yes, we're done
sta backup ; Save character at cursor position
jmp setcursor ; Draw cursor
; Move the mouse cursor x position to the value in A/X.
movex:
dex ; Is position [256..279]?
bmi :+ ; No, start with column 0
clc
adc #$0100 .MOD 7 ; Bias position
ldx #$0100 / 7 - 1 ; Bias column
: sec
: sbc #7 ; 280 positions / 40 columns
inx
bcs :-
stx column+1
dex ; Is position [256..279]?
bmi :+ ; No, start with column 0
clc
adc #$0100 .MOD 7 ; Bias position
ldx #$0100 / 7 - 1 ; Bias column
: sec
: sbc #7 ; 280 positions / 40 columns
inx
bcs :-
stx column+1
.ifdef __APPLE2ENH__
adc #7 / 2 ; Left or right half of 40-col column?
ldx #<LOWSCR ; Columns 1,3,5..79
bcs :+
.assert LOWSCR + 1 = HISCR, error
inx ; Columns 0,2,4..78
: stx switch+1
adc #7 / 2 ; Left or right half of 40-col column?
ldx #<LOWSCR ; Columns 1,3,5..79
bcs :+
.assert LOWSCR + 1 = HISCR, error
inx ; Columns 0,2,4..78
: stx switch+1
.endif
rts
rts
; Move the mouse cursor y position to the value in A/X.
movey:
tax ; ABCDExxx
lsr ; 0ABCDExx
lsr ; 00ABCDEx
lsr ; 000ABCDE
sta getscr+1
lsr ; 0000ABCD
and #%00000011 ; 000000CD
ora #>$0400 ; 000001CD
sta getscr+2
sta setscr+2
txa ; ABCDExxx
ror ; EABCDExx
and #%11100000 ; EAB00000
ora getscr+1 ; EABABCDE
and #%11111000 ; EABAB000
sta getscr+1
sta setscr+1
rts
tax ; ABCDExxx
lsr ; 0ABCDExx
lsr ; 00ABCDEx
lsr ; 000ABCDE
sta getscr+1
lsr ; 0000ABCD
and #%00000011 ; 000000CD
ora #>$0400 ; 000001CD
sta getscr+2
sta setscr+2
txa ; ABCDExxx
ror ; EABCDExx
and #%11100000 ; EAB00000
ora getscr+1 ; EABABCDE
and #%11111000 ; EABAB000
sta getscr+1
sta setscr+1
rts
+10 -10
View File
@@ -94,8 +94,8 @@ EOF_COUNT = 2
DATA_BUFFER .addr
.endstruct
.struct PREFIX
PARAM_COUNT .byte
PATHNAME .addr
PARAM_COUNT .byte
PATHNAME .addr
.endstruct
.struct OPEN
PARAM_COUNT .byte
@@ -130,12 +130,12 @@ EOF_COUNT = 2
.global mliparam
.global callmli
DEVNUM := $BF30 ; Most recent accessed device
DEVCNT := $BF31 ; Number of on-line devices (minus 1)
DEVLST := $BF32 ; Up to 14 units may be active
DATELO := $BF90 ; Bits 15-9 = year, 8-5 = month, 4-0 = day
TIMELO := $BF92 ; Bits 12-8 = hour, 5-0 = minute
LEVEL := $BF94 ; File level: used in open, flush, close
MACHID := $BF98 ; Machine identification
PFIXPTR := $BF9A ; If = 0, no prefix active
DEVNUM := $BF30 ; Most recent accessed device
DEVCNT := $BF31 ; Number of on-line devices (minus 1)
DEVLST := $BF32 ; Up to 14 units may be active
DATELO := $BF90 ; Bits 15-9 = year, 8-5 = month, 4-0 = day
TIMELO := $BF92 ; Bits 12-8 = hour, 5-0 = minute
LEVEL := $BF94 ; File level: used in open, flush, close
MACHID := $BF98 ; Machine identification
PFIXPTR := $BF9A ; If = 0, no prefix active
KVERSION:= $BFFF ; Kernel version number
+2 -2
View File
@@ -24,12 +24,12 @@ callmli:
beq oserr
; Call MLI and return
jsr $BF00 ; MLI call entry point
jsr $BF00 ; MLI call entry point
call: .byte $00
.addr mliparam
rts
; Load oserror code and return
oserr: lda #$01 ; "Bad system call number"
oserr: lda #$01 ; "Bad system call number"
sec
rts
+297 -297
View File
@@ -4,219 +4,219 @@
; Oliver Schmidt, 03.09.2005
;
.include "zeropage.inc"
.include "mouse-kernel.inc"
.include "apple2.inc"
.include "zeropage.inc"
.include "mouse-kernel.inc"
.include "apple2.inc"
; ------------------------------------------------------------------------
SETMOUSE = $12 ; Sets mouse mode
SERVEMOUSE = $13 ; Services mouse interrupt
READMOUSE = $14 ; Reads mouse position
CLEARMOUSE = $15 ; Clears mouse position to 0 (for delta mode)
POSMOUSE = $16 ; Sets mouse position to a user-defined pos
CLAMPMOUSE = $17 ; Sets mouse bounds in a window
HOMEMOUSE = $18 ; Sets mouse to upper-left corner of clamp win
INITMOUSE = $19 ; Resets mouse clamps to default values and
; sets mouse position to 0,0
SETMOUSE = $12 ; Sets mouse mode
SERVEMOUSE = $13 ; Services mouse interrupt
READMOUSE = $14 ; Reads mouse position
CLEARMOUSE = $15 ; Clears mouse position to 0 (for delta mode)
POSMOUSE = $16 ; Sets mouse position to a user-defined pos
CLAMPMOUSE = $17 ; Sets mouse bounds in a window
HOMEMOUSE = $18 ; Sets mouse to upper-left corner of clamp win
INITMOUSE = $19 ; Resets mouse clamps to default values and
; sets mouse position to 0,0
pos1_lo := $0478
pos1_hi := $0578
pos2_lo := $04F8
pos2_hi := $05F8
status := $0778
pos1_lo := $0478
pos1_hi := $0578
pos2_lo := $04F8
pos2_hi := $05F8
status := $0778
; ------------------------------------------------------------------------
.segment "JUMPTABLE"
.segment "JUMPTABLE"
; Driver signature
.byte $6D, $6F, $75 ; "mou"
.byte MOUSE_API_VERSION ; Mouse driver API version number
; Driver signature
.byte $6D, $6F, $75 ; "mou"
.byte MOUSE_API_VERSION ; Mouse driver API version number
; Jump table.
.addr INSTALL
.addr UNINSTALL
.addr HIDE
.addr SHOW
.addr SETBOX
.addr GETBOX
.addr MOVE
.addr BUTTONS
.addr POS
.addr INFO
.addr IOCTL
.addr IRQ
; Jump table.
.addr INSTALL
.addr UNINSTALL
.addr HIDE
.addr SHOW
.addr SETBOX
.addr GETBOX
.addr MOVE
.addr BUTTONS
.addr POS
.addr INFO
.addr IOCTL
.addr IRQ
; Mouse driver flags
.byte MOUSE_FLAG_EARLY_IRQ
; Callback table, set by the kernel before INSTALL is called
CHIDE: jmp $0000 ; Hide the cursor
CSHOW: jmp $0000 ; Show the cursor
CMOVEX: jmp $0000 ; Move the cursor to X coord
CMOVEY: jmp $0000 ; Move the cursor to Y coord
; Callback table, set by the kernel before INSTALL is called
CHIDE: jmp $0000 ; Hide the cursor
CSHOW: jmp $0000 ; Show the cursor
CMOVEX: jmp $0000 ; Move the cursor to X coord
CMOVEY: jmp $0000 ; Move the cursor to Y coord
; ------------------------------------------------------------------------
.bss
.bss
box: .tag MOUSE_BOX
info: .tag MOUSE_INFO
slot: .res 1
visible:.res 1
box: .tag MOUSE_BOX
info: .tag MOUSE_INFO
slot: .res 1
visible:.res 1
; ------------------------------------------------------------------------
.rodata
.rodata
offsets:.byte $05 ; Pascal 1.0 ID byte
.byte $07 ; Pascal 1.0 ID byte
.byte $0B ; Pascal 1.1 generic signature byte
.byte $0C ; Device signature byte
offsets:.byte $05 ; Pascal 1.0 ID byte
.byte $07 ; Pascal 1.0 ID byte
.byte $0B ; Pascal 1.1 generic signature byte
.byte $0C ; Device signature byte
values: .byte $38 ; Fixed
.byte $18 ; Fixed
.byte $01 ; Fixed
.byte $20 ; X-Y pointing device type 0
values: .byte $38 ; Fixed
.byte $18 ; Fixed
.byte $01 ; Fixed
.byte $20 ; X-Y pointing device type 0
size = * - values
size = * - values
inibox: .word 0 ; MinX
.word 0 ; MinY
.word 279 ; MaxX
.word 191 ; MaxY
inibox: .word 0 ; MinX
.word 0 ; MinY
.word 279 ; MaxX
.word 191 ; MaxY
; ------------------------------------------------------------------------
.data
.data
firmware:
; Lookup and patch firmware address lobyte
lookup: ldy $FF00,x ; Patched at runtime
sty jump+1 ; Modify code below
; Lookup and patch firmware address lobyte
lookup: ldy $FF00,x ; Patched at runtime
sty jump+1 ; Modify code below
; Apple II Mouse TechNote #1, Interrupt Environment with the Mouse:
; "Enter all mouse routines (...) with the X register set to $Cn
; and Y register set to $n0, where n = the slot number."
xparam: ldx #$FF ; Patched at runtime
yparam: ldy #$FF ; Patched at runtime
; Apple II Mouse TechNote #1, Interrupt Environment with the Mouse:
; "Enter all mouse routines (...) with the X register set to $Cn
; and Y register set to $n0, where n = the slot number."
xparam: ldx #$FF ; Patched at runtime
yparam: ldy #$FF ; Patched at runtime
jump: jmp $FFFF ; Patched at runtime
jump: jmp $FFFF ; Patched at runtime
; ------------------------------------------------------------------------
.code
.code
; INSTALL: Is called after the driver is loaded into memory. If possible,
; check if the hardware is present. Must return an MOUSE_ERR_xx code in A/X.
INSTALL:
lda #<$C000
sta ptr1
lda #>$C000
sta ptr1+1
lda #<$C000
sta ptr1
lda #>$C000
sta ptr1+1
; Search for AppleMouse II firmware in slots 1 - 7
next: inc ptr1+1
lda ptr1+1
cmp #>$C800
bcc :+
; Search for AppleMouse II firmware in slots 1 - 7
next: inc ptr1+1
lda ptr1+1
cmp #>$C800
bcc :+
; Mouse firmware not found
lda #<MOUSE_ERR_NO_DEVICE
ldx #>MOUSE_ERR_NO_DEVICE
rts
; Mouse firmware not found
lda #<MOUSE_ERR_NO_DEVICE
ldx #>MOUSE_ERR_NO_DEVICE
rts
; Check Pascal 1.1 Firmware Protocol ID bytes
: ldx #size - 1
: ldy offsets,x
lda values,x
cmp (ptr1),y
bne next
dex
bpl :-
; Check Pascal 1.1 Firmware Protocol ID bytes
: ldx #size - 1
: ldy offsets,x
lda values,x
cmp (ptr1),y
bne next
dex
bpl :-
; Get and patch firmware address hibyte
lda ptr1+1
sta lookup+2
sta xparam+1
sta jump+2
; Get and patch firmware address hibyte
lda ptr1+1
sta lookup+2
sta xparam+1
sta jump+2
; Disable interrupts now because setting the slot number makes
; the IRQ handler (maybe called due to some non-mouse IRQ) try
; calling the firmware which isn't correctly set up yet
sei
; Disable interrupts now because setting the slot number makes
; the IRQ handler (maybe called due to some non-mouse IRQ) try
; calling the firmware which isn't correctly set up yet
sei
; Convert to and save slot number
and #$0F
sta slot
; Convert to and save slot number
and #$0F
sta slot
; Convert to and patch I/O register index
asl
asl
asl
asl
sta yparam+1
; The AppleMouse II Card needs the ROM switched in
; to be able to detect an Apple //e and use RDVBL
bit $C082
; Convert to and patch I/O register index
asl
asl
asl
asl
sta yparam+1
; The AppleMouse II Card needs the ROM switched in
; to be able to detect an Apple //e and use RDVBL
bit $C082
; Reset mouse hardware
ldx #INITMOUSE
jsr firmware
; Switch in LC bank 2 for R/O
bit $C080
; Reset mouse hardware
ldx #INITMOUSE
jsr firmware
; Switch in LC bank 2 for R/O
bit $C080
; Turn mouse on
lda #%00000001
ldx #SETMOUSE
jsr firmware
; Turn mouse on
lda #%00000001
ldx #SETMOUSE
jsr firmware
; Set initial mouse clamps
lda #<inibox
ldx #>inibox
jsr SETBOX
; Set initial mouse clamps
lda #<inibox
ldx #>inibox
jsr SETBOX
; Set initial mouse position
ldx slot
lda #<(279 / 2)
sta pos1_lo,x
lda #>(279 / 2)
sta pos1_hi,x
lda #<(191 / 2)
sta pos2_lo,x
lda #>(191 / 2)
sta pos2_hi,x
ldx #POSMOUSE
jsr firmware
; Set initial mouse position
ldx slot
lda #<(279 / 2)
sta pos1_lo,x
lda #>(279 / 2)
sta pos1_hi,x
lda #<(191 / 2)
sta pos2_lo,x
lda #>(191 / 2)
sta pos2_hi,x
ldx #POSMOUSE
jsr firmware
; Update cursor
jsr update
; Update cursor
jsr update
; Turn VBL interrupt on
lda #%00001001
ldx #SETMOUSE
common: jsr firmware
; Turn VBL interrupt on
lda #%00001001
ldx #SETMOUSE
common: jsr firmware
; Enable interrupts and return success
cli
lda #<MOUSE_ERR_OK
ldx #>MOUSE_ERR_OK
rts
; Enable interrupts and return success
cli
lda #<MOUSE_ERR_OK
ldx #>MOUSE_ERR_OK
rts
; UNINSTALL: Is called before the driver is removed from memory.
; No return code required (the driver is removed from memory on return).
UNINSTALL:
; Hide cursor
sei
jsr CHIDE
; Hide cursor
sei
jsr CHIDE
; Turn mouse off
lda #%00000000
ldx #SETMOUSE
bne common ; Branch always
; Turn mouse off
lda #%00000000
ldx #SETMOUSE
bne common ; Branch always
; SETBOX: Set the mouse bounding box. The parameters are passed as they come
; from the C program, that is, a pointer to a mouse_box struct in A/X.
@@ -224,62 +224,62 @@ UNINSTALL:
; of the caller. It is not necessary to validate the parameters, trust the
; caller and save some code here. No return code required.
SETBOX:
sta ptr1
stx ptr1+1
sta ptr1
stx ptr1+1
; Set x clamps
ldx #$00
ldy #MOUSE_BOX::MINX
jsr :+
; Set y clamps
ldx #$01
ldy #MOUSE_BOX::MINY
; Set x clamps
ldx #$00
ldy #MOUSE_BOX::MINX
jsr :+
; Set y clamps
ldx #$01
ldy #MOUSE_BOX::MINY
; Apple II Mouse TechNote #1, Interrupt Environment with the Mouse:
; "Disable interrupts before placing position information in the
; screen holes."
: sei
; Apple II Mouse TechNote #1, Interrupt Environment with the Mouse:
; "Disable interrupts before placing position information in the
; screen holes."
: sei
; Set low clamp
lda (ptr1),y
sta box,y
sta pos1_lo
iny
lda (ptr1),y
sta box,y
sta pos1_hi
; Set low clamp
lda (ptr1),y
sta box,y
sta pos1_lo
iny
lda (ptr1),y
sta box,y
sta pos1_hi
; Skip one word
iny
iny
; Skip one word
iny
iny
; Set high clamp
iny
lda (ptr1),y
sta box,y
sta pos2_lo
iny
lda (ptr1),y
sta box,y
sta pos2_hi
; Set high clamp
iny
lda (ptr1),y
sta box,y
sta pos2_lo
iny
lda (ptr1),y
sta box,y
sta pos2_hi
txa
ldx #CLAMPMOUSE
bne common ; Branch always
txa
ldx #CLAMPMOUSE
bne common ; Branch always
; GETBOX: Return the mouse bounding box. The parameters are passed as they
; come from the C program, that is, a pointer to a mouse_box struct in A/X.
GETBOX:
sta ptr1
stx ptr1+1
sta ptr1
stx ptr1+1
ldy #.sizeof(MOUSE_BOX)-1
: lda box,y
sta (ptr1),y
dey
bpl :-
rts
ldy #.sizeof(MOUSE_BOX)-1
: lda box,y
sta (ptr1),y
dey
bpl :-
rts
; MOVE: Move the mouse to a new position. The position is passed as it comes
; from the C program, that is: x on the stack and y in A/X. The C wrapper will
@@ -287,148 +287,148 @@ GETBOX:
; No checks are done if the new position is valid (within the bounding box or
; the screen). No return code required.
MOVE:
ldy slot
sei
ldy slot
sei
; Set y
sta pos2_lo,y
txa
sta pos2_hi,y
; Set y
sta pos2_lo,y
txa
sta pos2_hi,y
tya
tax
ldy #$00 ; Start at top of stack
tya
tax
ldy #$00 ; Start at top of stack
; Set x
lda (sp),y
iny
sta pos1_lo,x
lda (sp),y
sta pos1_hi,x
; Set x
lda (sp),y
iny
sta pos1_lo,x
lda (sp),y
sta pos1_hi,x
; Update cursor
jsr update
; Update cursor
jsr update
ldx #POSMOUSE
bne common ; Branch always
ldx #POSMOUSE
bne common ; Branch always
; HIDE: Is called to hide the mouse cursor. The mouse kernel manages a
; counter for calls to show/hide, and the driver entry point is only called
; if the mouse is currently visible and should get hidden. For most drivers,
; no special action is required besides hiding the mouse cursor.
; no special action is required besides hiding the mouse cursor.
; No return code required.
HIDE:
dec visible
sei
jsr CHIDE
cli
rts
dec visible
sei
jsr CHIDE
cli
rts
; SHOW: Is called to show the mouse cursor. The mouse kernel manages a
; SHOW: Is called to show the mouse cursor. The mouse kernel manages a
; counter for calls to show/hide, and the driver entry point is only called
; if the mouse is currently hidden and should become visible. For most drivers,
; no special action is required besides enabling the mouse cursor.
; no special action is required besides enabling the mouse cursor.
; No return code required.
SHOW:
inc visible
rts
inc visible
rts
; BUTTONS: Return the button mask in A/X.
BUTTONS:
lda info + MOUSE_INFO::BUTTONS
ldx #$00
rts
lda info + MOUSE_INFO::BUTTONS
ldx #$00
rts
; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
; No return code required.
POS:
ldy #.sizeof(MOUSE_POS)-1
bne copy ; Branch always
ldy #.sizeof(MOUSE_POS)-1
bne copy ; Branch always
; INFO: Returns mouse position and current button mask in the MOUSE_INFO
; struct pointed to by ptr1. No return code required.
INFO:
ldy #.sizeof(MOUSE_INFO)-1
copy: sei
: lda info,y
sta (ptr1),y
dey
bpl :-
cli
rts
ldy #.sizeof(MOUSE_INFO)-1
copy: sei
: lda info,y
sta (ptr1),y
dey
bpl :-
cli
rts
; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; specific data in ptr1, and the ioctl code in A.
; Must return an MOUSE_ERR_xx code in A/X.
IOCTL:
lda #<MOUSE_ERR_INV_IOCTL
ldx #>MOUSE_ERR_INV_IOCTL
rts
lda #<MOUSE_ERR_INV_IOCTL
ldx #>MOUSE_ERR_INV_IOCTL
rts
; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
; registers are already saved, no parameters are passed, but the carry flag
; is clear on entry. The routine must return with carry set if the interrupt
; was handled, otherwise with carry clear.
IRQ:
; Check for installed mouse
lda slot
beq done
; Check for installed mouse
lda slot
beq done
; Check for mouse interrupt
ldx #SERVEMOUSE
jsr firmware
bcc :+
clc ; Interrupt not handled
done: rts
; Check for mouse interrupt
ldx #SERVEMOUSE
jsr firmware
bcc :+
clc ; Interrupt not handled
done: rts
: ldx #READMOUSE
jsr firmware
: ldx #READMOUSE
jsr firmware
; Get status
ldy slot
lda status,y
tax ; Save status
; Get status
ldy slot
lda status,y
tax ; Save status
; Extract button down values
asl ; C = Button 0 is currently down
and #%00100000 ; !Z = Button 1 is currently down
; Extract button down values
asl ; C = Button 0 is currently down
and #%00100000 ; !Z = Button 1 is currently down
; Set button mask
beq :+
lda #MOUSE_BTN_RIGHT
: bcc :+
ora #MOUSE_BTN_LEFT
: sta info + MOUSE_INFO::BUTTONS
; Set button mask
beq :+
lda #MOUSE_BTN_RIGHT
: bcc :+
ora #MOUSE_BTN_LEFT
: sta info + MOUSE_INFO::BUTTONS
; Check for mouse movement
txa ; Restore status
and #%00100000 ; X or Y changed since last READMOUSE
beq :+
; Check for mouse movement
txa ; Restore status
and #%00100000 ; X or Y changed since last READMOUSE
beq :+
; Remove the cursor at the old position
update: jsr CHIDE
; Remove the cursor at the old position
update: jsr CHIDE
; Get and set the new X position
ldy slot
lda pos1_lo,y
ldx pos1_hi,y
sta info + MOUSE_POS::XCOORD
stx info + MOUSE_POS::XCOORD+1
jsr CMOVEX
; Get and set the new X position
ldy slot
lda pos1_lo,y
ldx pos1_hi,y
sta info + MOUSE_POS::XCOORD
stx info + MOUSE_POS::XCOORD+1
jsr CMOVEX
; Get and set the new Y position
ldy slot
lda pos2_lo,y
ldx pos2_hi,y
sta info + MOUSE_POS::YCOORD
stx info + MOUSE_POS::YCOORD+1
jsr CMOVEY
; Get and set the new Y position
ldy slot
lda pos2_lo,y
ldx pos2_hi,y
sta info + MOUSE_POS::YCOORD
stx info + MOUSE_POS::YCOORD+1
jsr CMOVEY
; Check for visibility
: lda visible
beq :+
; Check for visibility
: lda visible
beq :+
; Draw the cursor at the new position
jsr CSHOW
: sec ; Interrupt handled
rts
; Draw the cursor at the new position
jsr CSHOW
: sec ; Interrupt handled
rts
+5 -5
View File
@@ -6,16 +6,16 @@
; const void mouse_static_stddrv[];
;
.export _mouse_static_stddrv
.ifdef __APPLE2ENH__
.import _a2e_stdmou_mou
.export _mouse_static_stddrv
.ifdef __APPLE2ENH__
.import _a2e_stdmou_mou
.else
.import _a2_stdmou_mou
.import _a2_stdmou_mou
.endif
.rodata
.ifdef __APPLE2ENH__
.ifdef __APPLE2ENH__
_mouse_static_stddrv := _a2e_stdmou_mou
.else
_mouse_static_stddrv := _a2_stdmou_mou
+4 -4
View File
@@ -6,13 +6,13 @@
; const char mouse_stddrv[];
;
.export _mouse_stddrv
.export _mouse_stddrv
.rodata
_mouse_stddrv:
.ifdef __APPLE2ENH__
.asciiz "A2E.STDMOU.MOU"
.ifdef __APPLE2ENH__
.asciiz "A2E.STDMOU.MOU"
.else
.asciiz "A2.STDMOU.MOU"
.asciiz "A2.STDMOU.MOU"
.endif
+121 -121
View File
@@ -4,28 +4,28 @@
; int open (const char* name, int flags, ...);
;
.export _open, closedirect, freebuffer
.export __filetype, __auxtype
.constructor raisefilelevel
.destructor closeallfiles, 5
.export _open, closedirect, freebuffer
.export __filetype, __auxtype
.constructor raisefilelevel
.destructor closeallfiles, 5
.import pushname, popname, __dos_type
.import iobuf_alloc, iobuf_free
.import addysp, incsp4, incaxy, pushax, popax
.import pushname, popname, __dos_type
.import iobuf_alloc, iobuf_free
.import addysp, incsp4, incaxy, pushax, popax
.include "zeropage.inc"
.include "errno.inc"
.include "fcntl.inc"
.include "mli.inc"
.include "filedes.inc"
.include "zeropage.inc"
.include "errno.inc"
.include "fcntl.inc"
.include "mli.inc"
.include "filedes.inc"
.segment "INIT"
.segment "INIT"
raisefilelevel:
; Raise file level
lda __dos_type
beq :+
inc LEVEL
lda __dos_type
beq :+
inc LEVEL
: rts
.code
@@ -37,14 +37,14 @@ _open:
dey
dey
dey
jsr addysp
jsr addysp
; Start with first fdtab slot
ldy #$00
ldy #$00
; Check for free fdtab slot
: lda fdtab + FD::REF_NUM,y
beq found
: lda fdtab + FD::REF_NUM,y
beq found
; Advance to next fdtab slot
.assert .sizeof(FD) = 4, error
@@ -54,149 +54,149 @@ _open:
iny
; Check for end of fdtab
cpy #MAX_FDS * .sizeof(FD)
bcc :-
cpy #MAX_FDS * .sizeof(FD)
bcc :-
; Load errno code
lda #EMFILE
lda #EMFILE
; Cleanup stack
errno: jsr incsp4 ; Preserves A
errno: jsr incsp4 ; Preserves A
; Set __errno
jmp __directerrno
jmp __directerrno
; Save fdtab slot
found: tya
pha
; Alloc I/O buffer
lda #<(fdtab + FD::BUFFER)
ldx #>(fdtab + FD::BUFFER)
jsr incaxy
jsr pushax
lda #$00
ldx #>$0100
jsr pushax ; Preserves A
ldx #>$0400
jsr iobuf_alloc
tay ; Save errno code
lda #<(fdtab + FD::BUFFER)
ldx #>(fdtab + FD::BUFFER)
jsr incaxy
jsr pushax
lda #$00
ldx #>$0100
jsr pushax ; Preserves A
ldx #>$0400
jsr iobuf_alloc
tay ; Save errno code
; Restore fdtab slot
pla
sta tmp2 ; Save fdtab slot
sta tmp2 ; Save fdtab slot
; Check for error
tya ; Restore errno code
bne errno
tya ; Restore errno code
bne errno
; Get and save flags
jsr popax
sta tmp3
jsr popax
sta tmp3
; Get and push name
jsr popax
jsr pushname
bne oserr1
jsr popax
jsr pushname
bne oserr1
; Set pushed name
lda sp
ldx sp+1
sta mliparam + MLI::OPEN::PATHNAME
stx mliparam + MLI::OPEN::PATHNAME+1
lda sp
ldx sp+1
sta mliparam + MLI::OPEN::PATHNAME
stx mliparam + MLI::OPEN::PATHNAME+1
; Check for create flag
lda tmp3 ; Restore flags
and #O_CREAT
beq open
lda tmp3 ; Restore flags
and #O_CREAT
beq open
; PATHNAME already set
.assert MLI::CREATE::PATHNAME = MLI::OPEN::PATHNAME, error
; Set all other parameters from template
ldx #(MLI::CREATE::CREATE_TIME+1) - (MLI::CREATE::PATHNAME+1) - 1
: lda CREATE,x
sta mliparam + MLI::CREATE::ACCESS,x
ldx #(MLI::CREATE::CREATE_TIME+1) - (MLI::CREATE::PATHNAME+1) - 1
: lda CREATE,x
sta mliparam + MLI::CREATE::ACCESS,x
dex
bpl :-
bpl :-
; Create file
lda #CREATE_CALL
ldx #CREATE_COUNT
jsr callmli
bcc open
lda #CREATE_CALL
ldx #CREATE_COUNT
jsr callmli
bcc open
; Check for ordinary errors
cmp #$47 ; "Duplicate filename"
bne oserr2
cmp #$47 ; "Duplicate filename"
bne oserr2
; Check for exclusive flag
lda tmp3 ; Restore flags
and #O_EXCL
beq open
lda tmp3 ; Restore flags
and #O_EXCL
beq open
lda #$47 ; "Duplicate filename"
lda #$47 ; "Duplicate filename"
; Cleanup name
oserr2: jsr popname ; Preserves A
oserr2: jsr popname ; Preserves A
oserr1: ldy tmp2 ; Restore fdtab slot
oserr1: ldy tmp2 ; Restore fdtab slot
; Cleanup I/O buffer
pha ; Save oserror code
jsr freebuffer
pla ; Restore oserror code
pha ; Save oserror code
jsr freebuffer
pla ; Restore oserror code
; Set __oserror
jmp __mappederrno
jmp __mappederrno
open: ldy tmp2 ; Restore fdtab slot
open: ldy tmp2 ; Restore fdtab slot
; Set allocated I/O buffer
ldx fdtab + FD::BUFFER+1,y
sta mliparam + MLI::OPEN::IO_BUFFER ; A = 0
stx mliparam + MLI::OPEN::IO_BUFFER+1
ldx fdtab + FD::BUFFER+1,y
sta mliparam + MLI::OPEN::IO_BUFFER ; A = 0
stx mliparam + MLI::OPEN::IO_BUFFER+1
; Open file
lda #OPEN_CALL
ldx #OPEN_COUNT
jsr callmli
bcs oserr2
lda #OPEN_CALL
ldx #OPEN_COUNT
jsr callmli
bcs oserr2
; Get and save fd
ldx mliparam + MLI::OPEN::REF_NUM
stx tmp1 ; Save fd
ldx mliparam + MLI::OPEN::REF_NUM
stx tmp1 ; Save fd
; Set flags and check for truncate flag
lda tmp3 ; Restore flags
sta fdtab + FD::FLAGS,y
and #O_TRUNC
beq done
lda tmp3 ; Restore flags
sta fdtab + FD::FLAGS,y
and #O_TRUNC
beq done
; Set fd and zero size
stx mliparam + MLI::EOF::REF_NUM
ldx #$02
lda #$00
: sta mliparam + MLI::EOF::EOF,x
stx mliparam + MLI::EOF::REF_NUM
ldx #$02
lda #$00
: sta mliparam + MLI::EOF::EOF,x
dex
bpl :-
bpl :-
; Set file size
lda #SET_EOF_CALL
ldx #EOF_COUNT
jsr callmli
bcc done
lda #SET_EOF_CALL
ldx #EOF_COUNT
jsr callmli
bcc done
; Cleanup file
pha ; Save oserror code
lda tmp1 ; Restore fd
jsr closedirect
pla ; Restore oserror code
bne oserr2 ; Branch always
pha ; Save oserror code
lda tmp1 ; Restore fd
jsr closedirect
pla ; Restore oserror code
bne oserr2 ; Branch always
; Store fd
done: lda tmp1 ; Restore fd
sta fdtab + FD::REF_NUM,y
done: lda tmp1 ; Restore fd
sta fdtab + FD::REF_NUM,y
; Convert fdtab slot to handle
.assert .sizeof(FD) = 4, error
@@ -205,46 +205,46 @@ done: lda tmp1 ; Restore fd
lsr
; Cleanup name
jsr popname ; Preserves A
jsr popname ; Preserves A
; Return success
ldx #$00
stx __oserror
ldx #$00
stx __oserror
rts
freebuffer:
; Free I/O buffer
lda #$00
ldx fdtab + FD::BUFFER+1,y
jmp iobuf_free
lda #$00
ldx fdtab + FD::BUFFER+1,y
jmp iobuf_free
closedirect:
; Set fd
sta mliparam + MLI::CLOSE::REF_NUM
sta mliparam + MLI::CLOSE::REF_NUM
; Call close
lda #CLOSE_CALL
ldx #CLOSE_COUNT
jmp callmli
lda #CLOSE_CALL
ldx #CLOSE_COUNT
jmp callmli
closeallfiles:
; All open files with current level (or higher)
lda #$00
jsr closedirect
lda #$00
jsr closedirect
; Restore original file level
lda __dos_type
beq :+
dec LEVEL
lda __dos_type
beq :+
dec LEVEL
: rts
.data
CREATE: .byte %11000011 ; ACCESS: Standard full access
CREATE: .byte %11000011 ; ACCESS: Standard full access
__filetype:
.byte $06 ; FILE_TYPE: Standard binary file
.byte $06 ; FILE_TYPE: Standard binary file
__auxtype:
.word $0000 ; AUX_TYPE: Load address N/A
.byte $01 ; STORAGE_TYPE: Standard seedling file
.word $0000 ; CREATE_DATE: Current date
.word $0000 ; CREATE_TIME: Current time
.word $0000 ; AUX_TYPE: Load address N/A
.byte $01 ; STORAGE_TYPE: Standard seedling file
.word $0000 ; CREATE_DATE: Current date
.word $0000 ; CREATE_TIME: Current time
+24 -24
View File
@@ -52,7 +52,7 @@ extern char _cwd[FILENAME_MAX];
/*****************************************************************************/
/* Code */
/* Code */
/*****************************************************************************/
@@ -64,44 +64,44 @@ DIR* __fastcall__ opendir (register const char* name)
/* Alloc DIR */
if ((dir = malloc (sizeof (*dir))) == NULL) {
/* May not have been done by malloc() */
_directerrno (ENOMEM);
/* May not have been done by malloc() */
_directerrno (ENOMEM);
/* Return failure */
return NULL;
/* Return failure */
return NULL;
}
/* Interpret dot as current working directory */
if (*name == '.') {
name = _cwd;
name = _cwd;
}
/* Open directory file */
if ((dir->fd = open (name, O_RDONLY)) != -1) {
/* Read directory key block */
if (read (dir->fd,
dir->block.bytes,
sizeof (dir->block)) == sizeof (dir->block)) {
/* Read directory key block */
if (read (dir->fd,
dir->block.bytes,
sizeof (dir->block)) == sizeof (dir->block)) {
/* Get directory entry infos from directory header */
dir->entry_length = dir->block.bytes[0x23];
dir->entries_per_block = dir->block.bytes[0x24];
/* Get directory entry infos from directory header */
dir->entry_length = dir->block.bytes[0x23];
dir->entries_per_block = dir->block.bytes[0x24];
/* Skip directory header entry */
dir->current_entry = 1;
/* Skip directory header entry */
dir->current_entry = 1;
/* Return success */
return dir;
}
/* Return success */
return dir;
}
/* EOF: Most probably no directory file at all */
if (_oserror == 0) {
_directerrno (EINVAL);
}
/* EOF: Most probably no directory file at all */
if (_oserror == 0) {
_directerrno (EINVAL);
}
/* Cleanup directory file */
close (dir->fd);
/* Cleanup directory file */
close (dir->fd);
}
/* Cleanup DIR */
+30 -30
View File
@@ -41,36 +41,36 @@ End:
.rodata
__sys_oserrlist:
sys_oserr_entry $01, "Bad system call number"
sys_oserr_entry $04, "Bad system call parameter count"
sys_oserr_entry $25, "Interrupt table full"
sys_oserr_entry $27, "I/O error"
sys_oserr_entry $28, "No device connected"
sys_oserr_entry $2B, "Disk write protected"
sys_oserr_entry $2E, "Disk switched"
sys_oserr_entry $2F, "Device off-line"
sys_oserr_entry $40, "Invalid pathname"
sys_oserr_entry $42, "Maximum number of files open"
sys_oserr_entry $43, "Invalid reference number"
sys_oserr_entry $44, "Directory not found"
sys_oserr_entry $45, "Volume not found"
sys_oserr_entry $46, "File not found"
sys_oserr_entry $47, "Duplicate filename"
sys_oserr_entry $48, "Volume full"
sys_oserr_entry $49, "Volume directory full"
sys_oserr_entry $4A, "Incompatible file format"
sys_oserr_entry $4B, "Unsupported storage_type"
sys_oserr_entry $4C, "End of file encountered"
sys_oserr_entry $4D, "Position out of range"
sys_oserr_entry $4E, "File access error"
sys_oserr_entry $50, "File is open"
sys_oserr_entry $51, "Directory structure damaged"
sys_oserr_entry $52, "Not a ProDOS disk"
sys_oserr_entry $53, "Invalid system call parameter"
sys_oserr_entry $55, "Volume Control Block table full"
sys_oserr_entry $56, "Bad buffer address"
sys_oserr_entry $57, "Duplicate volume"
sys_oserr_entry $5A, "File structure damaged"
sys_oserr_entry $01, "Bad system call number"
sys_oserr_entry $04, "Bad system call parameter count"
sys_oserr_entry $25, "Interrupt table full"
sys_oserr_entry $27, "I/O error"
sys_oserr_entry $28, "No device connected"
sys_oserr_entry $2B, "Disk write protected"
sys_oserr_entry $2E, "Disk switched"
sys_oserr_entry $2F, "Device off-line"
sys_oserr_entry $40, "Invalid pathname"
sys_oserr_entry $42, "Maximum number of files open"
sys_oserr_entry $43, "Invalid reference number"
sys_oserr_entry $44, "Directory not found"
sys_oserr_entry $45, "Volume not found"
sys_oserr_entry $46, "File not found"
sys_oserr_entry $47, "Duplicate filename"
sys_oserr_entry $48, "Volume full"
sys_oserr_entry $49, "Volume directory full"
sys_oserr_entry $4A, "Incompatible file format"
sys_oserr_entry $4B, "Unsupported storage_type"
sys_oserr_entry $4C, "End of file encountered"
sys_oserr_entry $4D, "Position out of range"
sys_oserr_entry $4E, "File access error"
sys_oserr_entry $50, "File is open"
sys_oserr_entry $51, "Directory structure damaged"
sys_oserr_entry $52, "Not a ProDOS disk"
sys_oserr_entry $53, "Invalid system call parameter"
sys_oserr_entry $55, "Volume Control Block table full"
sys_oserr_entry $56, "Bad buffer address"
sys_oserr_entry $57, "Duplicate volume"
sys_oserr_entry $5A, "File structure damaged"
sys_oserr_sentinel "Unknown error"
+40 -40
View File
@@ -4,59 +4,59 @@
; int __fastcall__ _osmaperrno (unsigned char oserror);
;
.export __osmaperrno
.export __osmaperrno
.include "errno.inc"
.include "errno.inc"
__osmaperrno:
ldx #ErrTabSize
: cmp ErrTab-2,x ; Search for the error code
beq :+ ; Jump if found
ldx #ErrTabSize
: cmp ErrTab-2,x ; Search for the error code
beq :+ ; Jump if found
dex
dex
bne :- ; Next entry
bne :- ; Next entry
; Code not found, return EUNKNOWN
lda #<EUNKNOWN
ldx #>EUNKNOWN
lda #<EUNKNOWN
ldx #>EUNKNOWN
rts
; Found the code
: lda ErrTab-1,x
ldx #$00 ; High byte always zero
: lda ErrTab-1,x
ldx #$00 ; High byte always zero
rts
.rodata
ErrTab: .byte $01, ENOSYS ; Bad system call number
.byte $04, EINVAL ; Bad system call parameter count
.byte $25, ENOMEM ; Interrupt table full
.byte $27, EIO ; I/O error
.byte $28, ENODEV ; No device connected
.byte $2B, EACCES ; Disk write protected
; .byte $2E, EUNKNOWN ; Disk switched
.byte $2F, ENODEV ; Device off-line
.byte $40, EINVAL ; Invalid pathname
.byte $42, EMFILE ; Maximum number of files open
.byte $43, EINVAL ; Invalid reference number
.byte $44, ENOENT ; Directory not found
.byte $45, ENOENT ; Volume not found
.byte $46, ENOENT ; File not found
.byte $47, EEXIST ; Duplicate filename
.byte $48, ENOSPC ; Volume full
.byte $49, ENOSPC ; Volume directory full
; .byte $4A, EUNKNOWN ; Incompatible file format
.byte $4B, EINVAL ; Unsupported storage_type
; .byte $4C, EUNKNOWN ; End of file encountered
.byte $4D, ESPIPE ; Position out of range
.byte $4E, EACCES ; File access error
.byte $50, EINVAL ; File is open
; .byte $51, EUNKNOWN ; Directory structure damaged
.byte $52, ENODEV ; Not a ProDOS volume
.byte $53, ERANGE ; Invalid system call parameter
.byte $55, EMFILE ; Volume Control Block table full
.byte $56, EINVAL ; Bad buffer address
; .byte $57, EUNKNOWN ; Duplicate volume
; .byte $5A, EUNKNOWN ; File structure damaged
ErrTab: .byte $01, ENOSYS ; Bad system call number
.byte $04, EINVAL ; Bad system call parameter count
.byte $25, ENOMEM ; Interrupt table full
.byte $27, EIO ; I/O error
.byte $28, ENODEV ; No device connected
.byte $2B, EACCES ; Disk write protected
; .byte $2E, EUNKNOWN ; Disk switched
.byte $2F, ENODEV ; Device off-line
.byte $40, EINVAL ; Invalid pathname
.byte $42, EMFILE ; Maximum number of files open
.byte $43, EINVAL ; Invalid reference number
.byte $44, ENOENT ; Directory not found
.byte $45, ENOENT ; Volume not found
.byte $46, ENOENT ; File not found
.byte $47, EEXIST ; Duplicate filename
.byte $48, ENOSPC ; Volume full
.byte $49, ENOSPC ; Volume directory full
; .byte $4A, EUNKNOWN ; Incompatible file format
.byte $4B, EINVAL ; Unsupported storage_type
; .byte $4C, EUNKNOWN ; End of file encountered
.byte $4D, ESPIPE ; Position out of range
.byte $4E, EACCES ; File access error
.byte $50, EINVAL ; File is open
; .byte $51, EUNKNOWN ; Directory structure damaged
.byte $52, ENODEV ; Not a ProDOS volume
.byte $53, ERANGE ; Invalid system call parameter
.byte $55, EMFILE ; Volume Control Block table full
.byte $56, EINVAL ; Bad buffer address
; .byte $57, EUNKNOWN ; Duplicate volume
; .byte $5A, EUNKNOWN ; File structure damaged
ErrTabSize = (* - ErrTab)
+2 -2
View File
@@ -5,8 +5,8 @@
; /* Initialize the random number generator */
;
.export __randomize
.import _srand
.export __randomize
.import _srand
.include "apple2.inc"
+9 -9
View File
@@ -4,17 +4,17 @@
; RDKEY routine
;
.export RDKEY
.export RDKEY
.include "apple2.inc"
.include "apple2.inc"
.segment "LOWCODE"
.segment "LOWCODE"
RDKEY:
; Switch in ROM and call RDKEY
bit $C082
jsr $FD0C ; Display prompt and read key from user input routine
; Switch in ROM and call RDKEY
bit $C082
jsr $FD0C ; Display prompt and read key from user input routine
; Switch in LC bank 2 for R/O and return
bit $C080
rts
; Switch in LC bank 2 for R/O and return
bit $C080
rts
+55 -55
View File
@@ -4,104 +4,104 @@
; int __fastcall__ read (int fd, void* buf, unsigned count);
;
.constructor initprompt
.export _read
.import rwprolog, rwcommon
.import RDKEY, COUT
.constructor initprompt
.export _read
.import rwprolog, rwcommon
.import RDKEY, COUT
.include "zeropage.inc"
.include "errno.inc"
.include "fcntl.inc"
.include "mli.inc"
.include "filedes.inc"
.include "apple2.inc"
.include "zeropage.inc"
.include "errno.inc"
.include "fcntl.inc"
.include "mli.inc"
.include "filedes.inc"
.include "apple2.inc"
.segment "INIT"
.segment "INIT"
initprompt:
; Set prompt <> ']' to let DOS 3.3 know that we're
; not in Applesoft immediate mode and thus keep it
; from scanning our device I/O for DOS commands.
lda #$80 ; Same value used at $D52C
sta PROMPT
lda #$80 ; Same value used at $D52C
sta PROMPT
rts
.code
_read:
; Get parameters
jsr rwprolog
bcs errno
tax ; Save fd
jsr rwprolog
bcs errno
tax ; Save fd
; Check for read access
lda fdtab + FD::FLAGS,y
and #O_RDONLY
beq einval
lda fdtab + FD::FLAGS,y
and #O_RDONLY
beq einval
; Check for device
txa ; Restore fd
bmi device
txa ; Restore fd
bmi device
; Do read
ldy #READ_CALL
jmp rwcommon
ldy #READ_CALL
jmp rwcommon
; Device succeeds always
device: lda #$00
sta __oserror
device: lda #$00
sta __oserror
; Set counter to zero
sta ptr3
sta ptr3+1
sta ptr3
sta ptr3+1
; Check for zero count
lda ptr2
ora ptr2+1
beq check
lda ptr2
ora ptr2+1
beq check
; Read from device and echo to device
next: jsr RDKEY
jsr COUT
next: jsr RDKEY
jsr COUT
; Clear hi bit and check for '\r'
and #$7F
cmp #$0D
bne :+
and #$7F
cmp #$0D
bne :+
; Replace with '\n' and set count to zero
lda #$0A
ldy #$00
sty ptr2
sty ptr2+1
lda #$0A
ldy #$00
sty ptr2
sty ptr2+1
; Put char into buf
: ldy #$00
sta (ptr1),y
: ldy #$00
sta (ptr1),y
; Increment pointer
inc ptr1
bne :+
inc ptr1+1
inc ptr1
bne :+
inc ptr1+1
; Increment counter
: inc ptr3
bne check
inc ptr3+1
: inc ptr3
bne check
inc ptr3+1
; Check for counter less than count
check: lda ptr3
cmp ptr2
bcc next
ldx ptr3+1
cpx ptr2+1
bcc next
check: lda ptr3
cmp ptr2
bcc next
ldx ptr3+1
cpx ptr2+1
bcc next
; Return success, AX already set
rts
; Load errno code
einval: lda #EINVAL
einval: lda #EINVAL
; Set __errno
errno: jmp __directerrno
errno: jmp __directerrno
+18 -18
View File
@@ -38,7 +38,7 @@
/*****************************************************************************/
/* Code */
/* Code */
/*****************************************************************************/
@@ -50,27 +50,27 @@ struct dirent* __fastcall__ readdir (register DIR* dir)
/* Search for the next active directory entry */
do {
/* Read next directory block if necessary */
if (dir->current_entry == dir->entries_per_block) {
if (read (dir->fd,
dir->block.bytes,
sizeof (dir->block)) != sizeof (dir->block)) {
/* Read next directory block if necessary */
if (dir->current_entry == dir->entries_per_block) {
if (read (dir->fd,
dir->block.bytes,
sizeof (dir->block)) != sizeof (dir->block)) {
/* Just return failure as read() has */
/* set errno if (and only if) no EOF */
return NULL;
}
/* Just return failure as read() has */
/* set errno if (and only if) no EOF */
return NULL;
}
/* Start with first entry in next block */
dir->current_entry = 0;
}
/* Start with first entry in next block */
dir->current_entry = 0;
}
/* Compute pointer to current entry */
entry = dir->block.content.entries +
dir->current_entry * dir->entry_length;
/* Compute pointer to current entry */
entry = dir->block.content.entries +
dir->current_entry * dir->entry_length;
/* Switch to next entry */
++dir->current_entry;
/* Switch to next entry */
++dir->current_entry;
} while (entry[0x00] == 0);
/* Move creation date/time to allow for next step below */
+11 -11
View File
@@ -4,19 +4,19 @@
; unsigned char __fastcall__ revers (unsigned char onoff)
;
.export _revers
.export _revers
.include "apple2.inc"
.include "apple2.inc"
_revers:
tax ; Test onoff
beq normal ; If zero, "normal" must be set
ldx #$3F+1 ; Set "inverse"
tax ; Test onoff
beq normal ; If zero, "normal" must be set
ldx #$3F+1 ; Set "inverse"
normal: dex ; $00->$FF, $40->$3F
lda #$00 ; Preload return code for "normal"
ldy INVFLG ; Load current flag value
stx INVFLG ; Save new flag value
bmi :+ ; Jump if current value is $FF (normal)
lda #$01 ; Return "inverse"
: ldx #$00
lda #$00 ; Preload return code for "normal"
ldy INVFLG ; Load current flag value
stx INVFLG ; Save new flag value
bmi :+ ; Jump if current value is $FF (normal)
lda #$01 ; Return "inverse"
: ldx #$00
rts
+10 -10
View File
@@ -39,7 +39,7 @@
/*****************************************************************************/
/* Code */
/* Code */
/*****************************************************************************/
@@ -49,17 +49,17 @@ void __fastcall__ rewinddir (register DIR* dir)
/* Rewind directory file */
if (lseek (dir->fd, 0, SEEK_SET)) {
/* Read directory key block */
if (read (dir->fd,
dir->block.bytes,
sizeof (dir->block)) == sizeof (dir->block)) {
/* Read directory key block */
if (read (dir->fd,
dir->block.bytes,
sizeof (dir->block)) == sizeof (dir->block)) {
/* Skip directory header entry */
dir->current_entry = 1;
/* Skip directory header entry */
dir->current_entry = 1;
/* Return success */
return;
}
/* Return success */
return;
}
}
/* Assert that no subsequent readdir() finds an active entry */
+32 -32
View File
@@ -2,59 +2,59 @@
; Oliver Schmidt, 12.01.2005
;
.export rwprolog, rwcommon, rwepilog
.import popax
.export rwprolog, rwcommon, rwepilog
.import popax
.include "zeropage.inc"
.include "errno.inc"
.include "fcntl.inc"
.include "mli.inc"
.include "filedes.inc"
.include "zeropage.inc"
.include "errno.inc"
.include "fcntl.inc"
.include "mli.inc"
.include "filedes.inc"
rwprolog:
; Save count
sta ptr2
stx ptr2+1
sta ptr2
stx ptr2+1
; Get and save buf
jsr popax
sta ptr1
stx ptr1+1
jsr popax
sta ptr1
stx ptr1+1
; Get and process fd
jsr popax
jmp getfd ; Returns A, Y and C
jsr popax
jmp getfd ; Returns A, Y and C
rwcommon:
; Set fd
sta mliparam + MLI::RW::REF_NUM
sta mliparam + MLI::RW::REF_NUM
; Set buf
lda ptr1
ldx ptr1+1
sta mliparam + MLI::RW::DATA_BUFFER
stx mliparam + MLI::RW::DATA_BUFFER+1
lda ptr1
ldx ptr1+1
sta mliparam + MLI::RW::DATA_BUFFER
stx mliparam + MLI::RW::DATA_BUFFER+1
; Set count
lda ptr2
ldx ptr2+1
sta mliparam + MLI::RW::REQUEST_COUNT
stx mliparam + MLI::RW::REQUEST_COUNT+1
lda ptr2
ldx ptr2+1
sta mliparam + MLI::RW::REQUEST_COUNT
stx mliparam + MLI::RW::REQUEST_COUNT+1
; Call read or write
tya
ldx #RW_COUNT
jsr callmli
bcc rwepilog
cmp #$4C ; "End of file encountered"
bne oserr
ldx #RW_COUNT
jsr callmli
bcc rwepilog
cmp #$4C ; "End of file encountered"
bne oserr
rwepilog:
; Return success
sta __oserror ; A = 0
lda mliparam + MLI::RW::TRANS_COUNT
ldx mliparam + MLI::RW::TRANS_COUNT+1
sta __oserror ; A = 0
lda mliparam + MLI::RW::TRANS_COUNT
ldx mliparam + MLI::RW::TRANS_COUNT+1
rts
; Set __oserror
oserr: jmp __mappederrno
oserr: jmp __mappederrno
+295 -295
View File
@@ -21,115 +21,115 @@
; interrupt handling assumes that the 65816 is in 6502-emulation mode.
;
.include "zeropage.inc"
.include "ser-kernel.inc"
.include "ser-error.inc"
.include "zeropage.inc"
.include "ser-kernel.inc"
.include "ser-error.inc"
; ------------------------------------------------------------------------
; Header. Includes jump table
.segment "JUMPTABLE"
.segment "JUMPTABLE"
; Driver signature
.byte $73, $65, $72 ; "ser"
.byte SER_API_VERSION ; Serial API version number
; Driver signature
.byte $73, $65, $72 ; "ser"
.byte SER_API_VERSION ; Serial API version number
; Jump table.
.addr INSTALL
.addr UNINSTALL
.addr OPEN
.addr CLOSE
.addr GET
.addr PUT
.addr STATUS
.addr IOCTL
.addr IRQ
; Jump table.
.addr INSTALL
.addr UNINSTALL
.addr OPEN
.addr CLOSE
.addr GET
.addr PUT
.addr STATUS
.addr IOCTL
.addr IRQ
;----------------------------------------------------------------------------
; I/O definitions
ACIA = $C088
ACIA_DATA = ACIA+0 ; Data register
ACIA_STATUS = ACIA+1 ; Status register
ACIA_CMD = ACIA+2 ; Command register
ACIA_CTRL = ACIA+3 ; Control register
ACIA = $C088
ACIA_DATA = ACIA+0 ; Data register
ACIA_STATUS = ACIA+1 ; Status register
ACIA_CMD = ACIA+2 ; Command register
ACIA_CTRL = ACIA+3 ; Control register
;----------------------------------------------------------------------------
; Global variables
.bss
.bss
RecvHead: .res 1 ; Head of receive buffer
RecvTail: .res 1 ; Tail of receive buffer
RecvFreeCnt: .res 1 ; Number of bytes in receive buffer
SendHead: .res 1 ; Head of send buffer
SendTail: .res 1 ; Tail of send buffer
SendFreeCnt: .res 1 ; Number of bytes in send buffer
RecvHead: .res 1 ; Head of receive buffer
RecvTail: .res 1 ; Tail of receive buffer
RecvFreeCnt: .res 1 ; Number of bytes in receive buffer
SendHead: .res 1 ; Head of send buffer
SendTail: .res 1 ; Tail of send buffer
SendFreeCnt: .res 1 ; Number of bytes in send buffer
Stopped: .res 1 ; Flow-stopped flag
RtsOff: .res 1 ;
Stopped: .res 1 ; Flow-stopped flag
RtsOff: .res 1 ;
RecvBuf: .res 256 ; Receive buffers: 256 bytes
SendBuf: .res 256 ; Send buffers: 256 bytes
RecvBuf: .res 256 ; Receive buffers: 256 bytes
SendBuf: .res 256 ; Send buffers: 256 bytes
Index: .res 1 ; I/O register index
Index: .res 1 ; I/O register index
.data
.data
Slot: .byte $02 ; Default to SSC in slot 2
Slot: .byte $02 ; Default to SSC in slot 2
.rodata
.rodata
; Tables used to translate RS232 params into register values
BaudTable: ; bit7 = 1 means setting is invalid
.byte $FF ; SER_BAUD_45_5
.byte $01 ; SER_BAUD_50
.byte $02 ; SER_BAUD_75
.byte $03 ; SER_BAUD_110
.byte $04 ; SER_BAUD_134_5
.byte $05 ; SER_BAUD_150
.byte $06 ; SER_BAUD_300
.byte $07 ; SER_BAUD_600
.byte $08 ; SER_BAUD_1200
.byte $09 ; SER_BAUD_1800
.byte $0A ; SER_BAUD_2400
.byte $0B ; SER_BAUD_3600
.byte $0C ; SER_BAUD_4800
.byte $0D ; SER_BAUD_7200
.byte $0E ; SER_BAUD_9600
.byte $0F ; SER_BAUD_19200
.byte $FF ; SER_BAUD_38400
.byte $FF ; SER_BAUD_57600
.byte $FF ; SER_BAUD_115200
.byte $FF ; SER_BAUD_230400
; Tables used to translate RS232 params into register values
BaudTable: ; bit7 = 1 means setting is invalid
.byte $FF ; SER_BAUD_45_5
.byte $01 ; SER_BAUD_50
.byte $02 ; SER_BAUD_75
.byte $03 ; SER_BAUD_110
.byte $04 ; SER_BAUD_134_5
.byte $05 ; SER_BAUD_150
.byte $06 ; SER_BAUD_300
.byte $07 ; SER_BAUD_600
.byte $08 ; SER_BAUD_1200
.byte $09 ; SER_BAUD_1800
.byte $0A ; SER_BAUD_2400
.byte $0B ; SER_BAUD_3600
.byte $0C ; SER_BAUD_4800
.byte $0D ; SER_BAUD_7200
.byte $0E ; SER_BAUD_9600
.byte $0F ; SER_BAUD_19200
.byte $FF ; SER_BAUD_38400
.byte $FF ; SER_BAUD_57600
.byte $FF ; SER_BAUD_115200
.byte $FF ; SER_BAUD_230400
BitTable:
.byte $60 ; SER_BITS_5
.byte $40 ; SER_BITS_6
.byte $20 ; SER_BITS_7
.byte $00 ; SER_BITS_8
.byte $60 ; SER_BITS_5
.byte $40 ; SER_BITS_6
.byte $20 ; SER_BITS_7
.byte $00 ; SER_BITS_8
StopTable:
.byte $00 ; SER_STOP_1
.byte $80 ; SER_STOP_2
.byte $00 ; SER_STOP_1
.byte $80 ; SER_STOP_2
ParityTable:
.byte $00 ; SER_PAR_NONE
.byte $20 ; SER_PAR_ODD
.byte $60 ; SER_PAR_EVEN
.byte $A0 ; SER_PAR_MARK
.byte $E0 ; SER_PAR_SPACE
.byte $00 ; SER_PAR_NONE
.byte $20 ; SER_PAR_ODD
.byte $60 ; SER_PAR_EVEN
.byte $A0 ; SER_PAR_MARK
.byte $E0 ; SER_PAR_SPACE
IdOfsTable:
.byte $05 ; Pascal 1.0 ID byte
.byte $07 ; Pascal 1.0 ID byte
.byte $0B ; Pascal 1.1 generic signature byte
.byte $0C ; Device signature byte
.byte $05 ; Pascal 1.0 ID byte
.byte $07 ; Pascal 1.0 ID byte
.byte $0B ; Pascal 1.1 generic signature byte
.byte $0C ; Device signature byte
IdValTable:
.byte $38 ; Fixed
.byte $18 ; Fixed
.byte $01 ; Fixed
.byte $31 ; Serial or parallel I/O card type 1
.byte $38 ; Fixed
.byte $18 ; Fixed
.byte $01 ; Fixed
.byte $31 ; Serial or parallel I/O card type 1
IdTableLen = * - IdValTable
IdTableLen = * - IdValTable
.code
.code
;----------------------------------------------------------------------------
; INSTALL: Is called after the driver is loaded into memory. If possible,
@@ -149,119 +149,119 @@ IdTableLen = * - IdValTable
INSTALL:
UNINSTALL:
CLOSE:
ldx Index ; Check for open port
beq :+
ldx Index ; Check for open port
beq :+
; Deactivate DTR and disable 6551 interrupts
lda #%00001010
sta ACIA_CMD,x
; Deactivate DTR and disable 6551 interrupts
lda #%00001010
sta ACIA_CMD,x
; Done, return an error code
: lda #<SER_ERR_OK
tax ; A is zero
stx Index ; Mark port as closed
rts
; Done, return an error code
: lda #<SER_ERR_OK
tax ; A is zero
stx Index ; Mark port as closed
rts
;----------------------------------------------------------------------------
; OPEN: A pointer to a ser_params structure is passed in ptr1.
; Must return an SER_ERR_xx code in a/x.
OPEN:
ldx #<$C000
stx ptr2
lda #>$C000
ora Slot
sta ptr2+1
; Check Pascal 1.1 Firmware Protocol ID bytes
: ldy IdOfsTable,x
lda IdValTable,x
cmp (ptr2),y
bne NoDevice
inx
cpx #IdTableLen
bcc :-
; Convert slot to I/O register index
lda Slot
asl
asl
asl
asl
tax
OPEN:
ldx #<$C000
stx ptr2
lda #>$C000
ora Slot
sta ptr2+1
; Check Pascal 1.1 Firmware Protocol ID bytes
: ldy IdOfsTable,x
lda IdValTable,x
cmp (ptr2),y
bne NoDevice
inx
cpx #IdTableLen
bcc :-
; Convert slot to I/O register index
lda Slot
asl
asl
asl
asl
tax
; Check if the handshake setting is valid
ldy #SER_PARAMS::HANDSHAKE ; Handshake
lda (ptr1),y
cmp #SER_HS_HW ; This is all we support
bne InvParam
; Check if the handshake setting is valid
ldy #SER_PARAMS::HANDSHAKE ; Handshake
lda (ptr1),y
cmp #SER_HS_HW ; This is all we support
bne InvParam
; Initialize buffers
ldy #$00
sty Stopped
sty RecvHead
sty RecvTail
sty SendHead
sty SendTail
dey ; Y = 255
sty RecvFreeCnt
sty SendFreeCnt
; Initialize buffers
ldy #$00
sty Stopped
sty RecvHead
sty RecvTail
sty SendHead
sty SendTail
dey ; Y = 255
sty RecvFreeCnt
sty SendFreeCnt
; Set the value for the control register, which contains stop bits,
; word length and the baud rate.
ldy #SER_PARAMS::BAUDRATE
lda (ptr1),y ; Baudrate index
tay
lda BaudTable,y ; Get 6551 value
bmi InvBaud ; Branch if rate not supported
sta tmp1
; Set the value for the control register, which contains stop bits,
; word length and the baud rate.
ldy #SER_PARAMS::BAUDRATE
lda (ptr1),y ; Baudrate index
tay
lda BaudTable,y ; Get 6551 value
bmi InvBaud ; Branch if rate not supported
sta tmp1
ldy #SER_PARAMS::DATABITS ; Databits
lda (ptr1),y
tay
lda BitTable,y
ora tmp1
sta tmp1
ldy #SER_PARAMS::DATABITS ; Databits
lda (ptr1),y
tay
lda BitTable,y
ora tmp1
sta tmp1
ldy #SER_PARAMS::STOPBITS ; Stopbits
lda (ptr1),y
tay
lda StopTable,y
ora tmp1
ora #%00010000 ; Receiver clock source = baudrate
sta ACIA_CTRL,x
ldy #SER_PARAMS::STOPBITS ; Stopbits
lda (ptr1),y
tay
lda StopTable,y
ora tmp1
ora #%00010000 ; Receiver clock source = baudrate
sta ACIA_CTRL,x
; Set the value for the command register. We remember the base value
; in RtsOff, since we will have to manipulate ACIA_CMD often.
ldy #SER_PARAMS::PARITY ; Parity
lda (ptr1),y
tay
lda ParityTable,y
ora #%00000001 ; DTR active
sta RtsOff
ora #%00001000 ; Enable receive interrupts
sta ACIA_CMD,x
; Set the value for the command register. We remember the base value
; in RtsOff, since we will have to manipulate ACIA_CMD often.
ldy #SER_PARAMS::PARITY ; Parity
lda (ptr1),y
tay
lda ParityTable,y
ora #%00000001 ; DTR active
sta RtsOff
ora #%00001000 ; Enable receive interrupts
sta ACIA_CMD,x
; Done
stx Index ; Mark port as open
lda #<SER_ERR_OK
tax ; A is zero
rts
; Done
stx Index ; Mark port as open
lda #<SER_ERR_OK
tax ; A is zero
rts
; Device (hardware) not found
NoDevice:lda #<SER_ERR_NO_DEVICE
ldx #>SER_ERR_NO_DEVICE
rts
; Device (hardware) not found
NoDevice:lda #<SER_ERR_NO_DEVICE
ldx #>SER_ERR_NO_DEVICE
rts
; Invalid parameter
InvParam:lda #<SER_ERR_INIT_FAILED
ldx #>SER_ERR_INIT_FAILED
rts
; Invalid parameter
InvParam:lda #<SER_ERR_INIT_FAILED
ldx #>SER_ERR_INIT_FAILED
rts
; Baud rate not available
InvBaud:lda #<SER_ERR_BAUD_UNAVAIL
ldx #>SER_ERR_BAUD_UNAVAIL
rts
; Baud rate not available
InvBaud:lda #<SER_ERR_BAUD_UNAVAIL
ldx #>SER_ERR_BAUD_UNAVAIL
rts
;----------------------------------------------------------------------------
; GET: Will fetch a character from the receive buffer and store it into the
@@ -269,86 +269,86 @@ InvBaud:lda #<SER_ERR_BAUD_UNAVAIL
; returned.
GET:
ldx Index
ldy SendFreeCnt ; Send data if necessary
iny ; Y == $FF?
beq :+
lda #$00 ; TryHard = false
jsr TryToSend
ldx Index
ldy SendFreeCnt ; Send data if necessary
iny ; Y == $FF?
beq :+
lda #$00 ; TryHard = false
jsr TryToSend
; Check for buffer empty
: lda RecvFreeCnt ; (25)
cmp #$FF
bne :+
lda #<SER_ERR_NO_DATA
ldx #>SER_ERR_NO_DATA
rts
; Check for buffer empty
: lda RecvFreeCnt ; (25)
cmp #$FF
bne :+
lda #<SER_ERR_NO_DATA
ldx #>SER_ERR_NO_DATA
rts
; Check for flow stopped & enough free: release flow control
: ldy Stopped ; (34)
beq :+
cmp #63
bcc :+
lda #$00
sta Stopped
lda RtsOff
ora #%00001000
sta ACIA_CMD,x
; Check for flow stopped & enough free: release flow control
: ldy Stopped ; (34)
beq :+
cmp #63
bcc :+
lda #$00
sta Stopped
lda RtsOff
ora #%00001000
sta ACIA_CMD,x
; Get byte from buffer
: ldy RecvHead ; (41)
lda RecvBuf,y
inc RecvHead
inc RecvFreeCnt
ldx #$00 ; (59)
sta (ptr1,x)
txa ; Return code = 0
rts
; Get byte from buffer
: ldy RecvHead ; (41)
lda RecvBuf,y
inc RecvHead
inc RecvFreeCnt
ldx #$00 ; (59)
sta (ptr1,x)
txa ; Return code = 0
rts
;----------------------------------------------------------------------------
; PUT: Output character in A.
; Must return an SER_ERR_xx code in a/x.
PUT:
ldx Index
ldx Index
; Try to send
ldy SendFreeCnt
iny ; Y = $FF?
beq :+
pha
lda #$00 ; TryHard = false
jsr TryToSend
pla
; Try to send
ldy SendFreeCnt
iny ; Y = $FF?
beq :+
pha
lda #$00 ; TryHard = false
jsr TryToSend
pla
; Put byte into send buffer & send
: ldy SendFreeCnt
bne :+
lda #<SER_ERR_OVERFLOW
ldx #>SER_ERR_OVERFLOW
rts
; Put byte into send buffer & send
: ldy SendFreeCnt
bne :+
lda #<SER_ERR_OVERFLOW
ldx #>SER_ERR_OVERFLOW
rts
: ldy SendTail
sta SendBuf,y
inc SendTail
dec SendFreeCnt
lda #$FF ; TryHard = true
jsr TryToSend
lda #<SER_ERR_OK
tax
rts
: ldy SendTail
sta SendBuf,y
inc SendTail
dec SendFreeCnt
lda #$FF ; TryHard = true
jsr TryToSend
lda #<SER_ERR_OK
tax
rts
;----------------------------------------------------------------------------
; STATUS: Return the status in the variable pointed to by ptr1.
; Must return an SER_ERR_xx code in a/x.
STATUS:
ldx Index
lda ACIA_STATUS,x
ldx #$00
sta (ptr1,x)
txa ; SER_ERR_OK
rts
ldx Index
lda ACIA_STATUS,x
ldx #$00
sta (ptr1,x)
txa ; SER_ERR_OK
rts
;----------------------------------------------------------------------------
; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
@@ -356,23 +356,23 @@ STATUS:
; Must return an SER_ERR_xx code in a/x.
IOCTL:
; Check data msb and code to be 0
ora ptr1+1
bne :+
; Check data msb and code to be 0
ora ptr1+1
bne :+
; Check data lsb to be [1..7]
ldx ptr1
beq :+
cpx #7+1
bcs :+
; Check data lsb to be [1..7]
ldx ptr1
beq :+
cpx #7+1
bcs :+
stx Slot
tax ; SER_ERR_OK
rts
stx Slot
tax ; SER_ERR_OK
rts
: lda #<SER_ERR_INV_IOCTL
ldx #>SER_ERR_INV_IOCTL
rts
: lda #<SER_ERR_INV_IOCTL
ldx #>SER_ERR_INV_IOCTL
rts
;----------------------------------------------------------------------------
; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
@@ -381,55 +381,55 @@ IOCTL:
; was handled, otherwise with carry clear.
IRQ:
ldx Index ; Check for open port
beq Done
lda ACIA_STATUS,x ; Check ACIA status for receive interrupt
and #$08
beq Done ; Jump if no ACIA interrupt
lda ACIA_DATA,x ; Get byte from ACIA
ldy RecvFreeCnt ; Check if we have free space left
beq Flow ; Jump if no space in receive buffer
ldy RecvTail ; Load buffer pointer
sta RecvBuf,y ; Store received byte in buffer
inc RecvTail ; Increment buffer pointer
dec RecvFreeCnt ; Decrement free space counter
ldy RecvFreeCnt ; Check for buffer space low
cpy #33
bcc Flow ; Assert flow control if buffer space low
rts ; Interrupt handled (carry already set)
ldx Index ; Check for open port
beq Done
lda ACIA_STATUS,x ; Check ACIA status for receive interrupt
and #$08
beq Done ; Jump if no ACIA interrupt
lda ACIA_DATA,x ; Get byte from ACIA
ldy RecvFreeCnt ; Check if we have free space left
beq Flow ; Jump if no space in receive buffer
ldy RecvTail ; Load buffer pointer
sta RecvBuf,y ; Store received byte in buffer
inc RecvTail ; Increment buffer pointer
dec RecvFreeCnt ; Decrement free space counter
ldy RecvFreeCnt ; Check for buffer space low
cpy #33
bcc Flow ; Assert flow control if buffer space low
rts ; Interrupt handled (carry already set)
; Assert flow control if buffer space too low
Flow: lda RtsOff
sta ACIA_CMD,x
sta Stopped
sec ; Interrupt handled
Done: rts
; Assert flow control if buffer space too low
Flow: lda RtsOff
sta ACIA_CMD,x
sta Stopped
sec ; Interrupt handled
Done: rts
;----------------------------------------------------------------------------
; Try to send a byte. Internal routine. A = TryHard
TryToSend:
sta tmp1 ; Remember tryHard flag
Again: lda SendFreeCnt
cmp #$FF
beq Quit ; Bail out
sta tmp1 ; Remember tryHard flag
Again: lda SendFreeCnt
cmp #$FF
beq Quit ; Bail out
; Check for flow stopped
lda Stopped
bne Quit ; Bail out
; Check for flow stopped
lda Stopped
bne Quit ; Bail out
; Check that ACIA is ready to send
lda ACIA_STATUS,x
and #$10
bne Send
bit tmp1 ; Keep trying if must try hard
bmi Again
Quit: rts
; Check that ACIA is ready to send
lda ACIA_STATUS,x
and #$10
bne Send
bit tmp1 ; Keep trying if must try hard
bmi Again
Quit: rts
; Send byte and try again
Send: ldy SendHead
lda SendBuf,y
sta ACIA_DATA,x
inc SendHead
inc SendFreeCnt
jmp Again
; Send byte and try again
Send: ldy SendHead
lda SendBuf,y
sta ACIA_DATA,x
inc SendHead
inc SendFreeCnt
jmp Again
+18 -18
View File
@@ -5,33 +5,33 @@
;
.export __syschdir
.import pushname, popname
.import initcwd
.import pushname, popname
.import initcwd
.include "zeropage.inc"
.include "mli.inc"
.include "zeropage.inc"
.include "mli.inc"
__syschdir:
; Push name
jsr pushname
bne oserr
jsr pushname
bne oserr
; Set pushed name
lda sp
ldx sp+1
sta mliparam + MLI::PREFIX::PATHNAME
stx mliparam + MLI::PREFIX::PATHNAME+1
lda sp
ldx sp+1
sta mliparam + MLI::PREFIX::PATHNAME
stx mliparam + MLI::PREFIX::PATHNAME+1
; Change directory
lda #SET_PREFIX_CALL
ldx #PREFIX_COUNT
jsr callmli
bcs cleanup
lda #SET_PREFIX_CALL
ldx #PREFIX_COUNT
jsr callmli
bcs cleanup
; Update current working directory
jsr initcwd ; Returns with A = 0
; Update current working directory
jsr initcwd ; Returns with A = 0
; Cleanup name
cleanup:jsr popname ; Preserves A
cleanup:jsr popname ; Preserves A
oserr: rts
oserr: rts
+27 -27
View File
@@ -5,51 +5,51 @@
;
.export __sysmkdir
.import pushname, popname
.import addysp, popax
.import pushname, popname
.import addysp, popax
.include "zeropage.inc"
.include "mli.inc"
.include "zeropage.inc"
.include "mli.inc"
__sysmkdir:
; Throw away all parameters except the name
dey
dey
jsr addysp
jsr addysp
; Get and push name
jsr popax
jsr pushname
bne oserr
jsr popax
jsr pushname
bne oserr
; Set pushed name
lda sp
ldx sp+1
sta mliparam + MLI::CREATE::PATHNAME
stx mliparam + MLI::CREATE::PATHNAME+1
lda sp
ldx sp+1
sta mliparam + MLI::CREATE::PATHNAME
stx mliparam + MLI::CREATE::PATHNAME+1
; Set all other parameters from template
ldx #(MLI::CREATE::CREATE_TIME+1) - (MLI::CREATE::PATHNAME+1) - 1
: lda CREATE,x
sta mliparam + MLI::CREATE::ACCESS,x
ldx #(MLI::CREATE::CREATE_TIME+1) - (MLI::CREATE::PATHNAME+1) - 1
: lda CREATE,x
sta mliparam + MLI::CREATE::ACCESS,x
dex
bpl :-
bpl :-
; Make directory
lda #CREATE_CALL
ldx #CREATE_COUNT
jsr callmli
lda #CREATE_CALL
ldx #CREATE_COUNT
jsr callmli
; Cleanup name
jsr popname ; Preserves A
jsr popname ; Preserves A
oserr: rts
oserr: rts
.rodata
CREATE: .byte %11000011 ; ACCESS: Standard full access
.byte $0F ; FILE_TYPE: Directory file
.word $0000 ; AUX_TYPE: N/A
.byte $0D ; STORAGE_TYPE: Linked directory file
.word $0000 ; CREATE_DATE: Current date
.word $0000 ; CREATE_TIME: Current time
CREATE: .byte %11000011 ; ACCESS: Standard full access
.byte $0F ; FILE_TYPE: Directory file
.word $0000 ; AUX_TYPE: N/A
.byte $0D ; STORAGE_TYPE: Linked directory file
.word $0000 ; CREATE_DATE: Current date
.word $0000 ; CREATE_TIME: Current time
+14 -14
View File
@@ -5,28 +5,28 @@
;
.export __sysremove
.import pushname, popname
.import pushname, popname
.include "zeropage.inc"
.include "mli.inc"
.include "zeropage.inc"
.include "mli.inc"
__sysremove:
; Push name
jsr pushname
bne oserr
jsr pushname
bne oserr
; Set pushed name
lda sp
ldx sp+1
sta mliparam + MLI::DESTROY::PATHNAME
stx mliparam + MLI::DESTROY::PATHNAME+1
lda sp
ldx sp+1
sta mliparam + MLI::DESTROY::PATHNAME
stx mliparam + MLI::DESTROY::PATHNAME+1
; Remove file
lda #DESTROY_CALL
ldx #DESTROY_COUNT
jsr callmli
lda #DESTROY_CALL
ldx #DESTROY_COUNT
jsr callmli
; Cleanup name
jsr popname ; Preserves A
jsr popname ; Preserves A
oserr: rts
oserr: rts
+33 -33
View File
@@ -5,55 +5,55 @@
;
.export __sysrename
.import pushname, popname
.import popax
.import pushname, popname
.import popax
.include "zeropage.inc"
.include "mli.inc"
.include "zeropage.inc"
.include "mli.inc"
__sysrename:
; Save newname
sta ptr2
stx ptr2+1
; Save newname
sta ptr2
stx ptr2+1
; Get and push oldname
jsr popax
jsr pushname
bne oserr1
jsr popax
jsr pushname
bne oserr1
; Save pushed oldname
lda sp
ldx sp+1
sta ptr3
stx ptr3+1
; Save pushed oldname
lda sp
ldx sp+1
sta ptr3
stx ptr3+1
; Restore and push newname
lda ptr2
ldx ptr2+1
jsr pushname
bne oserr2
lda ptr2
ldx ptr2+1
jsr pushname
bne oserr2
; Restore and set pushed oldname
lda ptr3
ldx ptr3+1
sta mliparam + MLI::RENAME::PATHNAME
stx mliparam + MLI::RENAME::PATHNAME+1
lda ptr3
ldx ptr3+1
sta mliparam + MLI::RENAME::PATHNAME
stx mliparam + MLI::RENAME::PATHNAME+1
; Set pushed newname
lda sp
ldx sp+1
sta mliparam + MLI::RENAME::NEW_PATHNAME
stx mliparam + MLI::RENAME::NEW_PATHNAME+1
lda sp
ldx sp+1
sta mliparam + MLI::RENAME::NEW_PATHNAME
stx mliparam + MLI::RENAME::NEW_PATHNAME+1
; Rename file
lda #RENAME_CALL
ldx #RENAME_COUNT
jsr callmli
lda #RENAME_CALL
ldx #RENAME_COUNT
jsr callmli
; Cleanup newname
jsr popname ; Preserves A
jsr popname ; Preserves A
; Cleanup oldname
oserr2: jmp popname ; Preserves A
oserr2: jmp popname ; Preserves A
oserr1: rts
oserr1: rts
+1 -1
View File
@@ -5,6 +5,6 @@
;
.export __sysrmdir
.import __sysremove
.import __sysremove
__sysrmdir := __sysremove
+43 -43
View File
@@ -10,54 +10,54 @@
;
.include "time.inc"
.include "zeropage.inc"
.include "mli.inc"
.include "zeropage.inc"
.include "mli.inc"
__systime:
; Update time
lda #GET_TIME_CALL
ldx #GET_TIME_COUNT
jsr callmli
bcs err
; Update time
lda #GET_TIME_CALL
ldx #GET_TIME_COUNT
jsr callmli
bcs err
lda DATELO+1
lsr
php ; Save month msb
cmp #70 ; Year < 70?
bcs :+ ; No, leave alone
adc #100 ; Move 19xx to 20xx
: sta TM + tm::tm_year
lda DATELO
tax ; Save day
plp ; Restore month msb
ror
lsr
lsr
lsr
lsr
beq err ; [1..12] allows for validity check
tay
dey ; Move [1..12] to [0..11]
sty TM + tm::tm_mon
txa ; Restore day
and #%00011111
sta TM + tm::tm_mday
lda DATELO+1
lsr
php ; Save month msb
cmp #70 ; Year < 70?
bcs :+ ; No, leave alone
adc #100 ; Move 19xx to 20xx
: sta TM + tm::tm_year
lda DATELO
tax ; Save day
plp ; Restore month msb
ror
lsr
lsr
lsr
lsr
beq err ; [1..12] allows for validity check
tay
dey ; Move [1..12] to [0..11]
sty TM + tm::tm_mon
txa ; Restore day
and #%00011111
sta TM + tm::tm_mday
lda TIMELO+1
sta TM + tm::tm_hour
lda TIMELO
sta TM + tm::tm_min
lda TIMELO+1
sta TM + tm::tm_hour
lda TIMELO
sta TM + tm::tm_min
lda #<TM
ldx #>TM
jmp _mktime
lda #<TM
ldx #>TM
jmp _mktime
err: lda #$FF
tax
sta sreg
sta sreg+1
rts ; Return -1
err: lda #$FF
tax
sta sreg
sta sreg+1
rts ; Return -1
.bss
.bss
TM: .tag tm
TM: .tag tm
+1 -1
View File
@@ -1,5 +1,5 @@
#################################################################################
# #
# #
# LOADER.SYSTEM - an Apple][ ProDOS 8 loader for cc65 programs (Oliver Schmidt) #
# #
#################################################################################
+170 -170
View File
@@ -4,231 +4,231 @@
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
A1L := $3C
A1H := $3D
STACK := $0100
BUF := $0200
PATHNAME := $0280
MLI := $BF00
VERSION := $FBB3
RDKEY := $FD0C
PRBYTE := $FDDA
COUT := $FDED
A1L := $3C
A1H := $3D
STACK := $0100
BUF := $0200
PATHNAME := $0280
MLI := $BF00
VERSION := $FBB3
RDKEY := $FD0C
PRBYTE := $FDDA
COUT := $FDED
QUIT_CALL = $65
QUIT_CALL = $65
GET_FILE_INFO_CALL = $C4
OPEN_CALL = $C8
READ_CALL = $CA
CLOSE_CALL = $CC
OPEN_CALL = $C8
READ_CALL = $CA
CLOSE_CALL = $CC
FILE_NOT_FOUND_ERR = $46
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.import __CODE_0300_SIZE__, __DATA_0300_SIZE__
.import __CODE_0300_LOAD__, __CODE_0300_RUN__
.import __CODE_0300_SIZE__, __DATA_0300_SIZE__
.import __CODE_0300_LOAD__, __CODE_0300_RUN__
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.segment "DATA_2000"
.segment "DATA_2000"
GET_FILE_INFO_PARAM:
.byte $0A ;PARAM_COUNT
.addr PATHNAME ;PATHNAME
.byte $00 ;ACCESS
.byte $00 ;FILE_TYPE
FILE_INFO_ADDR: .word $0000 ;AUX_TYPE
.byte $00 ;STORAGE_TYPE
.word $0000 ;BLOCKS_USED
.word $0000 ;MOD_DATE
.word $0000 ;MOD_TIME
.word $0000 ;CREATE_DATE
.word $0000 ;CREATE_TIME
.byte $0A ;PARAM_COUNT
.addr PATHNAME ;PATHNAME
.byte $00 ;ACCESS
.byte $00 ;FILE_TYPE
FILE_INFO_ADDR: .word $0000 ;AUX_TYPE
.byte $00 ;STORAGE_TYPE
.word $0000 ;BLOCKS_USED
.word $0000 ;MOD_DATE
.word $0000 ;MOD_TIME
.word $0000 ;CREATE_DATE
.word $0000 ;CREATE_TIME
OPEN_PARAM:
.byte $03 ;PARAM_COUNT
.addr PATHNAME ;PATHNAME
.addr MLI - 1024 ;IO_BUFFER
OPEN_REF: .byte $00 ;REF_NUM
.byte $03 ;PARAM_COUNT
.addr PATHNAME ;PATHNAME
.addr MLI - 1024 ;IO_BUFFER
OPEN_REF: .byte $00 ;REF_NUM
LOADING:
.byte $0D
.asciiz "Loading "
.byte $0D
.asciiz "Loading "
ELLIPSES:
.byte " ...", $0D, $0D, $00
.byte " ...", $0D, $0D, $00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.segment "DATA_0300"
.segment "DATA_0300"
READ_PARAM:
.byte $04 ;PARAM_COUNT
READ_REF: .byte $00 ;REF_NUM
READ_ADDR: .addr $0000 ;DATA_BUFFER
.word $FFFF ;REQUEST_COUNT
.word $0000 ;TRANS_COUNT
.byte $04 ;PARAM_COUNT
READ_REF: .byte $00 ;REF_NUM
READ_ADDR: .addr $0000 ;DATA_BUFFER
.word $FFFF ;REQUEST_COUNT
.word $0000 ;TRANS_COUNT
CLOSE_PARAM:
.byte $01 ;PARAM_COUNT
CLOSE_REF: .byte $00 ;REF_NUM
.byte $01 ;PARAM_COUNT
CLOSE_REF: .byte $00 ;REF_NUM
QUIT_PARAM:
.byte $04 ;PARAM_COUNT
.byte $00 ;QUIT_TYPE
.word $0000 ;RESERVED
.byte $00 ;RESERVED
.word $0000 ;RESERVED
.byte $04 ;PARAM_COUNT
.byte $00 ;QUIT_TYPE
.word $0000 ;RESERVED
.byte $00 ;RESERVED
.word $0000 ;RESERVED
FILE_NOT_FOUND:
.asciiz "... File Not Found"
.asciiz "... File Not Found"
ERROR_NUMBER:
.asciiz "... Error $"
.asciiz "... Error $"
PRESS_ANY_KEY:
.asciiz " - Press Any Key "
.asciiz " - Press Any Key "
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.segment "CODE_2000"
.segment "CODE_2000"
jmp :+
.byte $EE
.byte $EE
.byte 65
STARTUP:.res 65
jmp :+
.byte $EE
.byte $EE
.byte 65
STARTUP:.res 65
; Reset stack
: ldx #$FF
txs
; Reset stack
: ldx #$FF
txs
; Relocate CODE_0300 and DATA_0300
ldx #<(__CODE_0300_SIZE__ + __DATA_0300_SIZE__)
: lda __CODE_0300_LOAD__ - 1,x
sta __CODE_0300_RUN__ - 1,x
dex
bne :-
; Relocate CODE_0300 and DATA_0300
ldx #<(__CODE_0300_SIZE__ + __DATA_0300_SIZE__)
: lda __CODE_0300_LOAD__ - 1,x
sta __CODE_0300_RUN__ - 1,x
dex
bne :-
; Remove ".SYSTEM" from pathname
lda PATHNAME
sec
sbc #.strlen(".SYSTEM")
sta PATHNAME
; Remove ".SYSTEM" from pathname
lda PATHNAME
sec
sbc #.strlen(".SYSTEM")
sta PATHNAME
; Add trailing '\0' to pathname
tax
lda #$00
sta PATHNAME + 1,x
; Add trailing '\0' to pathname
tax
lda #$00
sta PATHNAME + 1,x
; Copy ProDOS startup filename and trailing '\0' to stack
ldx STARTUP
lda #$00
beq :++ ; bra
: lda STARTUP + 1,x
: sta STACK,x
dex
bpl :--
; Copy ProDOS startup filename and trailing '\0' to stack
ldx STARTUP
lda #$00
beq :++ ; bra
: lda STARTUP + 1,x
: sta STACK,x
dex
bpl :--
; Provide some user feedback
lda #<LOADING
ldx #>LOADING
jsr PRINT
lda #<(PATHNAME + 1)
ldx #>(PATHNAME + 1)
jsr PRINT
lda #<ELLIPSES
ldx #>ELLIPSES
jsr PRINT
; Provide some user feedback
lda #<LOADING
ldx #>LOADING
jsr PRINT
lda #<(PATHNAME + 1)
ldx #>(PATHNAME + 1)
jsr PRINT
lda #<ELLIPSES
ldx #>ELLIPSES
jsr PRINT
jsr MLI
.byte GET_FILE_INFO_CALL
.word GET_FILE_INFO_PARAM
bcc :+
jmp ERROR
jsr MLI
.byte GET_FILE_INFO_CALL
.word GET_FILE_INFO_PARAM
bcc :+
jmp ERROR
: jsr MLI
.byte OPEN_CALL
.word OPEN_PARAM
bcc :+
jmp ERROR
: jsr MLI
.byte OPEN_CALL
.word OPEN_PARAM
bcc :+
jmp ERROR
; Copy file reference number
: lda OPEN_REF
sta READ_REF
sta CLOSE_REF
; Copy file reference number
: lda OPEN_REF
sta READ_REF
sta CLOSE_REF
; Get load address from aux-type
lda FILE_INFO_ADDR
ldx FILE_INFO_ADDR + 1
sta READ_ADDR
stx READ_ADDR + 1
; Get load address from aux-type
lda FILE_INFO_ADDR
ldx FILE_INFO_ADDR + 1
sta READ_ADDR
stx READ_ADDR + 1
; It's high time to leave this place
jmp __CODE_0300_RUN__
; It's high time to leave this place
jmp __CODE_0300_RUN__
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.segment "CODE_0300"
.segment "CODE_0300"
jsr MLI
.byte READ_CALL
.word READ_PARAM
bcs ERROR
jsr MLI
.byte READ_CALL
.word READ_PARAM
bcs ERROR
jsr MLI
.byte CLOSE_CALL
.word CLOSE_PARAM
bcs ERROR
jsr MLI
.byte CLOSE_CALL
.word CLOSE_PARAM
bcs ERROR
; Copy REM token and startup filename to BASIC input buffer
ldx #$00
lda #$B2
bne :++ ; bra
: inx
lda a:STACK - 1,x
: sta BUF,x
bne :--
; Go for it ...
jmp (READ_ADDR)
; Copy REM token and startup filename to BASIC input buffer
ldx #$00
lda #$B2
bne :++ ; bra
: inx
lda a:STACK - 1,x
: sta BUF,x
bne :--
; Go for it ...
jmp (READ_ADDR)
PRINT:
sta A1L
stx A1H
ldx VERSION
ldy #$00
: lda (A1L),y
beq :++
cpx #$06 ; //e ?
beq :+
cmp #$60 ; lowercase ?
bcc :+
and #$5F ; -> uppercase
: ora #$80
jsr COUT
iny
bne :-- ; bra
: rts
sta A1L
stx A1H
ldx VERSION
ldy #$00
: lda (A1L),y
beq :++
cpx #$06 ; //e ?
beq :+
cmp #$60 ; lowercase ?
bcc :+
and #$5F ; -> uppercase
: ora #$80
jsr COUT
iny
bne :-- ; bra
: rts
ERROR:
cmp #FILE_NOT_FOUND_ERR
bne :+
lda #<FILE_NOT_FOUND
ldx #>FILE_NOT_FOUND
jsr PRINT
beq :++ ; bra
: pha
lda #<ERROR_NUMBER
ldx #>ERROR_NUMBER
jsr PRINT
pla
jsr PRBYTE
: lda #<PRESS_ANY_KEY
ldx #>PRESS_ANY_KEY
jsr PRINT
jsr RDKEY
jsr MLI
.byte QUIT_CALL
.word QUIT_PARAM
cmp #FILE_NOT_FOUND_ERR
bne :+
lda #<FILE_NOT_FOUND
ldx #>FILE_NOT_FOUND
jsr PRINT
beq :++ ; bra
: pha
lda #<ERROR_NUMBER
ldx #>ERROR_NUMBER
jsr PRINT
pla
jsr PRBYTE
: lda #<PRESS_ANY_KEY
ldx #>PRESS_ANY_KEY
jsr PRINT
jsr RDKEY
jsr MLI
.byte QUIT_CALL
.word QUIT_PARAM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+51 -51
View File
@@ -9,12 +9,12 @@
;
.ifdef __APPLE2ENH__
.export _textframexy, _textframe
.import popa, pusha, _gotoxy
.import chlinedirect, cvlinedirect
.export _textframexy, _textframe
.import popa, pusha, _gotoxy
.import chlinedirect, cvlinedirect
.include "zeropage.inc"
.include "apple2.inc"
.include "zeropage.inc"
.include "apple2.inc"
WIDTH = tmp2
HEIGHT = tmp3
@@ -23,60 +23,60 @@ YORIGIN = ptr1
_textframexy:
sec
bra :+
bra :+
_textframe:
clc
: ldx INVFLG
phx ; Save character display mode
ldx #$FF
stx INVFLG ; Set normal character display mode
pha ; Save index
jsr popa ; Get height
sta HEIGHT
jsr popa ; Get width
sta WIDTH
lda CH
ldx CV
bcc noxy
jsr popa ; Get y
: ldx INVFLG
phx ; Save character display mode
ldx #$FF
stx INVFLG ; Set normal character display mode
pha ; Save index
jsr popa ; Get height
sta HEIGHT
jsr popa ; Get width
sta WIDTH
lda CH
ldx CV
bcc noxy
jsr popa ; Get y
tax
jsr popa ; Get x
noxy: sta XORIGIN
stx YORIGIN
plx ; Restore index
loop: lda XOFFS,x
jsr popa ; Get x
noxy: sta XORIGIN
stx YORIGIN
plx ; Restore index
loop: lda XOFFS,x
clc
bpl :+ ; Relative to left edge?
adc WIDTH
: adc XORIGIN
jsr pusha
lda YOFFS,x
bpl :+ ; Relative to left edge?
adc WIDTH
: adc XORIGIN
jsr pusha
lda YOFFS,x
clc
bpl :+ ; Relative to top?
adc HEIGHT
: adc YORIGIN
jsr _gotoxy ; Call this one, will pop params
bpl :+ ; Relative to top?
adc HEIGHT
: adc YORIGIN
jsr _gotoxy ; Call this one, will pop params
txa
tay
lsr ; Get bit 0 (vline) into carry
lda LENGTH,x
phx ; Save index
ldx CHAR,y
bcc hline
lsr ; Get bit 0 (vline) into carry
lda LENGTH,x
phx ; Save index
ldx CHAR,y
bcc hline
clc
adc HEIGHT
jsr cvlinedirect
bra next
hline: adc WIDTH
jsr chlinedirect
next: plx ; Restore index
adc HEIGHT
jsr cvlinedirect
bra next
hline: adc WIDTH
jsr chlinedirect
next: plx ; Restore index
inx
txa
and #$03 ; Mask style
bne loop
and #$03 ; Mask style
bne loop
pla
sta INVFLG ; Restore character display mode
sta INVFLG ; Restore character display mode
rts
.rodata
@@ -88,21 +88,21 @@ next: plx ; Restore index
; x offset for the line starting point
; - a positive value means relative to the frame left edge
; - a negative value menas relative to the frame right edge
XOFFS: .byte 0, 0, 0, <-2, 1, 0, 1, <-2
XOFFS: .byte 0, 0, 0, <-2, 1, 0, 1, <-2
; y offset for the line starting point
; - a positive value means relative to the frame top
; - a negative value menas relative to the frame bottom
YOFFS: .byte 0, 1, <-2, 1, 0, 0, <-2, 0
YOFFS: .byte 0, 1, <-2, 1, 0, 0, <-2, 0
; length of the line relative to the frame size
; - a negative value for hlines means shorter than the width
; - a negative value for vlines menas shorter than the height
LENGTH: .byte 0, <-2, 0, <-2, <-2, 0, <-2, 0
LENGTH: .byte 0, <-2, 0, <-2, <-2, 0, <-2, 0
; character to use for drawing the line
; - hibit set means normal printable character
; - hibit clear means MouseText character
CHAR: .byte '_'|$80, '_', 'L', 'Z', 'L', 'Z', '_'|$80, '_'
CHAR: .byte '_'|$80, '_', 'L', 'Z', 'L', 'Z', '_'|$80, '_'
.endif ; __APPLE2ENH__
+252 -252
View File
@@ -5,55 +5,55 @@
; Oliver Schmidt <ol.sc@web.de>
;
.include "zeropage.inc"
.include "zeropage.inc"
.include "tgi-kernel.inc"
.include "tgi-error.inc"
.include "apple2.inc"
.include "tgi-kernel.inc"
.include "tgi-error.inc"
.include "apple2.inc"
; ------------------------------------------------------------------------
; Zero page stuff
HBASL := $26
HMASK := $30
PAGE := $E6
SCALE := $E7
ROT := $F9
HBASL := $26
HMASK := $30
PAGE := $E6
SCALE := $E7
ROT := $F9
; Graphics entry points, by cbmnut (applenut??) cbmnut@hushmail.com
TEXT := $F399 ; Return to text screen
HGR2 := $F3D8 ; Initialize and clear hi-res page 2.
HGR := $F3E2 ; Initialize and clear hi-res page 1.
HCLR := $F3F2 ; Clear the current hi-res screen to black.
BKGND := $F3F6 ; Clear the current hi-res screen to the
TEXT := $F399 ; Return to text screen
HGR2 := $F3D8 ; Initialize and clear hi-res page 2.
HGR := $F3E2 ; Initialize and clear hi-res page 1.
HCLR := $F3F2 ; Clear the current hi-res screen to black.
BKGND := $F3F6 ; Clear the current hi-res screen to the
; last plotted color (from ($1C).
HPOSN := $F411 ; Positions the hi-res cursor without
HPOSN := $F411 ; Positions the hi-res cursor without
; plotting a point.
; Enter with (A) = Y-coordinate, and
; (Y,X) = X-coordinate.
HPLOT := $F457 ; Calls HPOSN and tries to plot a dot at
HPLOT := $F457 ; Calls HPOSN and tries to plot a dot at
; the cursor's position. If you are
; trying to plot a non-white color at
; a complementary color position, no
; dot will be plotted.
HLIN := $F53A ; Draws a line from the last plotted
HLIN := $F53A ; Draws a line from the last plotted
; point or line destination to:
; (X,A) = X-coordinate, and
; (Y) = Y-coordinate.
HFIND := $F5CB ; Converts the hi-res coursor's position
HFIND := $F5CB ; Converts the hi-res coursor's position
; back to X- and Y-coordinates; stores
; X-coordinate at $E0,E1 and Y-coordinate
; at $E2.
DRAW := $F601 ; Draws a shape. Enter with (Y,X) = the
DRAW := $F601 ; Draws a shape. Enter with (Y,X) = the
; address of the shape table, and (A) =
; the rotation factor. Uses the current
; color.
XDRAW := $F65D ; Draws a shape by inverting the existing
XDRAW := $F65D ; Draws a shape by inverting the existing
; color of the dots the shape draws over.
; Same entry parameters as DRAW.
SETHCOL := $F6EC ; Set the hi-res color to (X), where (X)
SETHCOL := $F6EC ; Set the hi-res color to (X), where (X)
; must be between 0 and 7.
; ------------------------------------------------------------------------
@@ -61,100 +61,100 @@ SETHCOL := $F6EC ; Set the hi-res color to (X), where (X)
; Variables mapped to the zero page segment variables. Some of these are
; used for passing parameters to the driver.
X1 := ptr1
Y1 := ptr2
X2 := ptr3
Y2 := ptr4
X1 := ptr1
Y1 := ptr2
X2 := ptr3
Y2 := ptr4
; ------------------------------------------------------------------------
.segment "JUMPTABLE"
.segment "JUMPTABLE"
; Header. Includes jump table and constants.
; First part of the header is a structure that has a magic and defines the
; capabilities of the driver
.byte $74, $67, $69 ; "tgi"
.byte TGI_API_VERSION ; TGI API version number
.word 280 ; X resolution
.word 192 ; Y resolution
.byte 8 ; Number of drawing colors
pages: .byte 2 ; Number of screens available
.byte 7 ; System font X size
.byte 8 ; System font Y size
.word $00EA ; Aspect ratio (based on 4/3 display)
.byte $74, $67, $69 ; "tgi"
.byte TGI_API_VERSION ; TGI API version number
.word 280 ; X resolution
.word 192 ; Y resolution
.byte 8 ; Number of drawing colors
pages: .byte 2 ; Number of screens available
.byte 7 ; System font X size
.byte 8 ; System font Y size
.word $00EA ; Aspect ratio (based on 4/3 display)
.byte 0 ; TGI driver flags
; Next comes the jump table. With the exception of IRQ, all entries must be
; valid and may point to an RTS for test versions (function not implemented).
.addr INSTALL
.addr UNINSTALL
.addr INIT
.addr DONE
.addr GETERROR
.addr CONTROL
.addr CLEAR
.addr SETVIEWPAGE
.addr SETDRAWPAGE
.addr SETCOLOR
.addr SETPALETTE
.addr GETPALETTE
.addr GETDEFPALETTE
.addr SETPIXEL
.addr GETPIXEL
.addr LINE
.addr BAR
.addr TEXTSTYLE
.addr OUTTEXT
.addr INSTALL
.addr UNINSTALL
.addr INIT
.addr DONE
.addr GETERROR
.addr CONTROL
.addr CLEAR
.addr SETVIEWPAGE
.addr SETDRAWPAGE
.addr SETCOLOR
.addr SETPALETTE
.addr GETPALETTE
.addr GETDEFPALETTE
.addr SETPIXEL
.addr GETPIXEL
.addr LINE
.addr BAR
.addr TEXTSTYLE
.addr OUTTEXT
.addr 0 ; IRQ entry is unused
; ------------------------------------------------------------------------
.bss
.bss
; Absolute variables used in the code
ERROR: .res 1 ; Error code
ERROR: .res 1 ; Error code
; ------------------------------------------------------------------------
.rodata
.rodata
; Constants and tables
DEFPALETTE: .byte $00, $01, $02, $03, $04, $05, $06, $07
FONT:
; Beagle Bros Shape Mechanic font F.ASCII.SMALL
; modified to exactly reproduce the text glyphs
.incbin "a2.hi.fnt"
; Beagle Bros Shape Mechanic font F.ASCII.SMALL
; modified to exactly reproduce the text glyphs
.incbin "a2.hi.fnt"
; ------------------------------------------------------------------------
.code
.code
; INSTALL routine. Is called after the driver is loaded into memory. May
; initialize anything that has to be done just once. Is probably empty
; most of the time.
; Must set an error code: NO
INSTALL:
.ifdef __APPLE2ENH__
; No page switching if 80 column store is enabled
bit RD80COL
bpl :+
lda #$01
sta pages
: .endif
.ifdef __APPLE2ENH__
; No page switching if 80 column store is enabled
bit RD80COL
bpl :+
lda #$01
sta pages
: .endif
; Fall through
; Fall through
; UNINSTALL routine. Is called before the driver is removed from memory. May
; clean up anything done by INSTALL but is probably empty most of the time.
; Must set an error code: NO
UNINSTALL:
rts
rts
; INIT: Changes an already installed device from text mode to graphics mode.
; Note that INIT/DONE may be called multiple times while the driver
@@ -166,132 +166,132 @@ UNINSTALL:
; active, so there is no need to protect against that.
; Must set an error code: YES
INIT:
; Switch into graphics mode
bit MIXCLR
bit HIRES
bit TXTCLR
; Switch into graphics mode
bit MIXCLR
bit HIRES
bit TXTCLR
; Beagle Bros Shape Mechanic fonts don't
; scale well so use fixed scaling factor
lda #$01
sta SCALE
; Beagle Bros Shape Mechanic fonts don't
; scale well so use fixed scaling factor
lda #$01
sta SCALE
; Done, reset the error code
lda #TGI_ERR_OK
sta ERROR
rts
; Done, reset the error code
lda #TGI_ERR_OK
sta ERROR
rts
; DONE: Will be called to switch the graphics device back into text mode.
; The graphics kernel will never call DONE when no graphics mode is active,
; so there is no need to protect against that.
; Must set an error code: NO
DONE:
; Switch into text mode
bit TXTSET
bit LOWSCR
; Switch into text mode
bit TXTSET
bit LOWSCR
.ifdef __APPLE2ENH__
; Limit SET80COL-HISCR to text
bit LORES
.endif
.ifdef __APPLE2ENH__
; Limit SET80COL-HISCR to text
bit LORES
.endif
; Reset the text window top
lda #$00
sta WNDTOP
rts
; Reset the text window top
lda #$00
sta WNDTOP
rts
; GETERROR: Return the error code in A and clear it.
GETERROR:
lda ERROR
ldx #TGI_ERR_OK
stx ERROR
rts
lda ERROR
ldx #TGI_ERR_OK
stx ERROR
rts
; CONTROL: Platform/driver specific entry point.
; Must set an error code: YES
CONTROL:
; Check data msb and code to be 0
ora ptr1+1
bne err
; Check data msb and code to be 0
ora ptr1+1
bne err
; Check data lsb to be [0..1]
lda ptr1
cmp #1+1
bcs err
; Check data lsb to be [0..1]
lda ptr1
cmp #1+1
bcs err
; Set text window top
tax
beq :+
lda #20
: sta WNDTOP
; Set text window top
tax
beq :+
lda #20
: sta WNDTOP
; Switch 4 lines of text
.assert MIXCLR + 1 = MIXSET, error
lda MIXCLR,x ; No BIT absolute,X available
; Switch 4 lines of text
.assert MIXCLR + 1 = MIXSET, error
lda MIXCLR,x ; No BIT absolute,X available
; Done, reset the error code
lda #TGI_ERR_OK
beq :+ ; Branch always
; Done, reset the error code
lda #TGI_ERR_OK
beq :+ ; Branch always
; Done, set the error code
err: lda #TGI_ERR_INV_ARG
: sta ERROR
rts
; Done, set the error code
err: lda #TGI_ERR_INV_ARG
: sta ERROR
rts
; CLEAR: Clears the screen.
; Must set an error code: NO
CLEAR:
bit $C082 ; Switch in ROM
jsr HCLR
bit $C080 ; Switch in LC bank 2 for R/O
rts
bit $C082 ; Switch in ROM
jsr HCLR
bit $C080 ; Switch in LC bank 2 for R/O
rts
; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
; The page number is already checked to be valid by the graphics kernel.
; Must set an error code: NO (will only be called if page ok)
SETVIEWPAGE:
tax
.assert LOWSCR + 1 = HISCR, error
lda LOWSCR,x ; No BIT absolute,X available
rts
tax
.assert LOWSCR + 1 = HISCR, error
lda LOWSCR,x ; No BIT absolute,X available
rts
; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
; The page number is already checked to be valid by the graphics kernel.
; Must set an error code: NO (will only be called if page ok)
SETDRAWPAGE:
tax
beq :+
lda #>$4000 ; Page 2
.byte $2C ; BIT absolute
: lda #>$2000 ; Page 1
sta PAGE
rts
tax
beq :+
lda #>$4000 ; Page 2
.byte $2C ; BIT absolute
: lda #>$2000 ; Page 1
sta PAGE
rts
; SETCOLOR: Set the drawing color (in A). The new color is already checked
; to be in a valid range (0..maxcolor-1).
; Must set an error code: NO (will only be called if color ok)
SETCOLOR:
bit $C082 ; Switch in ROM
tax
jsr SETHCOL
bit $C080 ; Switch in LC bank 2 for R/O
rts
bit $C082 ; Switch in ROM
tax
jsr SETHCOL
bit $C080 ; Switch in LC bank 2 for R/O
rts
; SETPALETTE: Set the palette (not available with all drivers/hardware).
; A pointer to the palette is passed in ptr1. Must set an error if palettes
; are not supported
; Must set an error code: YES
SETPALETTE:
lda #TGI_ERR_INV_FUNC
sta ERROR
rts
lda #TGI_ERR_INV_FUNC
sta ERROR
rts
; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
; set the palette should return the default palette here, so there's no
; way for this function to fail.
; Must set an error code: NO
GETPALETTE:
; Fall through
; Fall through
; GETDEFPALETTE: Return the default palette for the driver in A/X. All
; drivers should return something reasonable here, even drivers that don't
@@ -299,147 +299,147 @@ GETPALETTE:
; of the (not changeable) palette.
; Must set an error code: NO (all drivers must have a default palette)
GETDEFPALETTE:
lda #<DEFPALETTE
ldx #>DEFPALETTE
rts
lda #<DEFPALETTE
ldx #>DEFPALETTE
rts
; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
; color. The coordinates passed to this function are never outside the
; visible screen area, so there is no need for clipping inside this function.
; Must set an error code: NO
SETPIXEL:
bit $C082 ; Switch in ROM
ldx X1
ldy X1+1
lda Y1
jsr HPLOT
bit $C080 ; Switch in LC bank 2 for R/O
rts
bit $C082 ; Switch in ROM
ldx X1
ldy X1+1
lda Y1
jsr HPLOT
bit $C080 ; Switch in LC bank 2 for R/O
rts
; GETPIXEL: Read the color value of a pixel and return it in A/X. The
; coordinates passed to this function are never outside the visible screen
; area, so there is no need for clipping inside this function.
GETPIXEL:
bit $C082 ; Switch in ROM
ldx X1
ldy X1+1
lda Y1
jsr HPOSN
lda (HBASL),y
and HMASK
asl
beq :+ ; 0 (black)
lda #$03 ; 3 (white)
: bcc :+
adc #$03 ; += 4 (black -> black2, white -> white2)
: ldx #$00
bit $C080 ; Switch in LC bank 2 for R/O
rts
bit $C082 ; Switch in ROM
ldx X1
ldy X1+1
lda Y1
jsr HPOSN
lda (HBASL),y
and HMASK
asl
beq :+ ; 0 (black)
lda #$03 ; 3 (white)
: bcc :+
adc #$03 ; += 4 (black -> black2, white -> white2)
: ldx #$00
bit $C080 ; Switch in LC bank 2 for R/O
rts
; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
; X2/Y2 = ptr3/ptr4 using the current drawing color.
; Must set an error code: NO
LINE:
bit $C082 ; Switch in ROM
ldx X1
ldy X1+1
lda Y1
jsr HPOSN
lda X2
ldx X2+1
ldy Y2
jsr HLIN
bit $C080 ; Switch in LC bank 2 for R/O
rts
bit $C082 ; Switch in ROM
ldx X1
ldy X1+1
lda Y1
jsr HPOSN
lda X2
ldx X2+1
ldy Y2
jsr HLIN
bit $C080 ; Switch in LC bank 2 for R/O
rts
; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
; Contrary to most other functions, the graphics kernel will sort and clip
; the coordinates before calling the driver, so on entry the following
; conditions are valid:
; X1 <= X2
; Y1 <= Y2
; (X1 >= 0) && (X1 < XRES)
; (X2 >= 0) && (X2 < XRES)
; (Y1 >= 0) && (Y1 < YRES)
; (Y2 >= 0) && (Y2 < YRES)
; X1 <= X2
; Y1 <= Y2
; (X1 >= 0) && (X1 < XRES)
; (X2 >= 0) && (X2 < XRES)
; (Y1 >= 0) && (Y1 < YRES)
; (Y2 >= 0) && (Y2 < YRES)
; Must set an error code: NO
BAR:
inc Y2
: lda Y2
pha
lda Y1
sta Y2
jsr LINE
pla
sta Y2
inc Y1
cmp Y1
bne :-
rts
inc Y2
: lda Y2
pha
lda Y1
sta Y2
jsr LINE
pla
sta Y2
inc Y1
cmp Y1
bne :-
rts
; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
; direction is passend in X/Y, the text direction is passed in A.
; Must set an error code: NO
TEXTSTYLE:
cmp #TGI_TEXT_VERTICAL
bne :+
lda #48
: sta ROT
rts
cmp #TGI_TEXT_VERTICAL
bne :+
lda #48
: sta ROT
rts
; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
; current text style. The text to output is given as a zero terminated
; string with address in ptr3.
; Must set an error code: NO
OUTTEXT:
bit $C082 ; Switch in ROM
lda X1
ldy X1+1
ldx ROT
php ; Save Z flag
beq :+ ; Not horizontal
sec
sbc #$07 ; Adjust X
bcs :+
dey
: tax
lda Y1
plp ; Restore Z flag
bne :+ ; Not vertical
sec
sbc #$07 ; Adjust Y
: jsr HPOSN
clc
lda FONT+2*99 ; "connection char"
adc #<FONT
sta ptr4
lda FONT+2*99+1 ; "connection char"
adc #>FONT
sta ptr4+1
ldy #$00
: lda (ptr3),y
beq :+
sty tmp1 ; Save string index
sec
sbc #$1F ; No control chars
asl ; Offset * 2
tay
clc
lda FONT,y
adc #<FONT
tax
lda FONT+1,y
adc #>FONT
tay
lda ROT
jsr DRAW ; Draw char from string
ldx ptr4
ldy ptr4+1
lda ROT
jsr DRAW ; Draw "connection char"
ldy tmp1 ; Restore string index
iny
bne :- ; Branch always
: bit $C080 ; Switch in LC bank 2 for R/O
rts
bit $C082 ; Switch in ROM
lda X1
ldy X1+1
ldx ROT
php ; Save Z flag
beq :+ ; Not horizontal
sec
sbc #$07 ; Adjust X
bcs :+
dey
: tax
lda Y1
plp ; Restore Z flag
bne :+ ; Not vertical
sec
sbc #$07 ; Adjust Y
: jsr HPOSN
clc
lda FONT+2*99 ; "connection char"
adc #<FONT
sta ptr4
lda FONT+2*99+1 ; "connection char"
adc #>FONT
sta ptr4+1
ldy #$00
: lda (ptr3),y
beq :+
sty tmp1 ; Save string index
sec
sbc #$1F ; No control chars
asl ; Offset * 2
tay
clc
lda FONT,y
adc #<FONT
tax
lda FONT+1,y
adc #>FONT
tay
lda ROT
jsr DRAW ; Draw char from string
ldx ptr4
ldy ptr4+1
lda ROT
jsr DRAW ; Draw "connection char"
ldy tmp1 ; Restore string index
iny
bne :- ; Branch always
: bit $C080 ; Switch in LC bank 2 for R/O
rts
+181 -181
View File
@@ -5,106 +5,106 @@
; Oliver Schmidt <ol.sc@web.de>
;
.include "zeropage.inc"
.include "zeropage.inc"
.include "tgi-kernel.inc"
.include "tgi-error.inc"
.include "apple2.inc"
.include "tgi-kernel.inc"
.include "tgi-error.inc"
.include "apple2.inc"
; ------------------------------------------------------------------------
; Zero page stuff
H2 := $2C
COLOR := $30
H2 := $2C
COLOR := $30
; ROM entry points
TEXT := $F399
PLOT := $F800
HLINE := $F819
CLRSC2 := $F838
SETCOL := $F864
SCRN := $F871
SETGR := $FB40
HOME := $FC58
TEXT := $F399
PLOT := $F800
HLINE := $F819
CLRSC2 := $F838
SETCOL := $F864
SCRN := $F871
SETGR := $FB40
HOME := $FC58
; Used for passing parameters to the driver
X1 := ptr1
Y1 := ptr2
X2 := ptr3
Y2 := ptr4
X1 := ptr1
Y1 := ptr2
X2 := ptr3
Y2 := ptr4
; ------------------------------------------------------------------------
.segment "JUMPTABLE"
.segment "JUMPTABLE"
; Header. Includes jump table and constants.
; First part of the header is a structure that has a magic and defines the
; capabilities of the driver
.byte $74, $67, $69 ; "tgi"
.byte TGI_API_VERSION ; TGI API version number
.word 40 ; X resolution
.word 48 ; Y resolution
.byte 16 ; Number of drawing colors
.byte 1 ; Number of screens available
.byte 8 ; System font X size
.byte 8 ; System font Y size
.word $0198 ; Aspect ratio (based on 4/3 display)
.byte $74, $67, $69 ; "tgi"
.byte TGI_API_VERSION ; TGI API version number
.word 40 ; X resolution
.word 48 ; Y resolution
.byte 16 ; Number of drawing colors
.byte 1 ; Number of screens available
.byte 8 ; System font X size
.byte 8 ; System font Y size
.word $0198 ; Aspect ratio (based on 4/3 display)
.byte 0 ; TGI driver flags
; Next comes the jump table. With the exception of IRQ, all entries must be
; valid and may point to an RTS for test versions (function not implemented).
.addr INSTALL
.addr UNINSTALL
.addr INIT
.addr DONE
.addr GETERROR
.addr CONTROL
.addr CLEAR
.addr SETVIEWPAGE
.addr SETDRAWPAGE
.addr SETCOLOR
.addr SETPALETTE
.addr GETPALETTE
.addr GETDEFPALETTE
.addr SETPIXEL
.addr GETPIXEL
.addr LINE
.addr BAR
.addr TEXTSTYLE
.addr OUTTEXT
.addr INSTALL
.addr UNINSTALL
.addr INIT
.addr DONE
.addr GETERROR
.addr CONTROL
.addr CLEAR
.addr SETVIEWPAGE
.addr SETDRAWPAGE
.addr SETCOLOR
.addr SETPALETTE
.addr GETPALETTE
.addr GETDEFPALETTE
.addr SETPIXEL
.addr GETPIXEL
.addr LINE
.addr BAR
.addr TEXTSTYLE
.addr OUTTEXT
.addr 0 ; IRQ entry is unused
; ------------------------------------------------------------------------
.bss
.bss
ERROR: .res 1 ; Error code
MIX: .res 1 ; 4 lines of text
ERROR: .res 1 ; Error code
MIX: .res 1 ; 4 lines of text
; ------------------------------------------------------------------------
.rodata
.rodata
DEFPALETTE: .byte $00, $01, $02, $03, $04, $05, $06, $07
.byte $08, $09, $0A, $0B, $0C, $0D, $0E, $0F
.byte $08, $09, $0A, $0B, $0C, $0D, $0E, $0F
TGI2COL: .byte $00, $0C, $03, $0F, $01, $09, $06, $02
.byte $04, $05, $07, $08, $0A, $0B, $0D, $0E
.byte $04, $05, $07, $08, $0A, $0B, $0D, $0E
COL2TGI: .byte $00, $04, $07, $02, $08, $09, $06, $0A
.byte $0B, $05, $0C, $0D, $01, $0E, $0F, $03
.byte $0B, $05, $0C, $0D, $01, $0E, $0F, $03
MAXY: .byte 47, 39
MAXY: .byte 47, 39
; ------------------------------------------------------------------------
.code
.code
; INIT: Changes an already installed device from text mode to graphics mode.
; Note that INIT/DONE may be called multiple times while the driver
@@ -116,168 +116,168 @@ MAXY: .byte 47, 39
; active, so there is no need to protect against that.
; Must set an error code: YES
INIT:
; Switch into graphics mode
bit $C082 ; Switch in ROM
jsr SETGR
bit MIXCLR
bit $C080 ; Switch in LC bank 2 for R/O
; Switch into graphics mode
bit $C082 ; Switch in ROM
jsr SETGR
bit MIXCLR
bit $C080 ; Switch in LC bank 2 for R/O
; Done, reset the error code
lda #TGI_ERR_OK
sta ERROR
sta MIX
; Done, reset the error code
lda #TGI_ERR_OK
sta ERROR
sta MIX
; Fall through
; Fall through
; INSTALL routine. Is called after the driver is loaded into memory. May
; initialize anything that has to be done just once. Is probably empty
; most of the time.
; Must set an error code: NO
INSTALL:
; Fall through
; Fall through
; UNINSTALL routine. Is called before the driver is removed from memory. May
; clean up anything done by INSTALL but is probably empty most of the time.
; Must set an error code: NO
UNINSTALL:
; Fall through
; Fall through
; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
; The page number is already checked to be valid by the graphics kernel.
; Must set an error code: NO (will only be called if page ok)
SETVIEWPAGE:
; Fall through
; Fall through
; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
; The page number is already checked to be valid by the graphics kernel.
; Must set an error code: NO (will only be called if page ok)
SETDRAWPAGE:
; Fall through
; Fall through
; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
; direction is passend in X/Y, the text direction is passed in A.
; Must set an error code: NO
TEXTSTYLE:
; Fall through
; Fall through
; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
; current text style. The text to output is given as a zero terminated
; string with address in ptr3.
; Must set an error code: NO
OUTTEXT:
rts
rts
; DONE: Will be called to switch the graphics device back into text mode.
; The graphics kernel will never call DONE when no graphics mode is active,
; so there is no need to protect against that.
; Must set an error code: NO
DONE:
bit $C082 ; Switch in ROM
jsr TEXT
jsr HOME
bit $C080 ; Switch in LC bank 2 for R/O
rts
bit $C082 ; Switch in ROM
jsr TEXT
jsr HOME
bit $C080 ; Switch in LC bank 2 for R/O
rts
; GETERROR: Return the error code in A and clear it.
GETERROR:
lda ERROR
ldx #TGI_ERR_OK
stx ERROR
rts
lda ERROR
ldx #TGI_ERR_OK
stx ERROR
rts
; CLEAR: Clears the screen.
; Must set an error code: NO
CLEAR:
bit $C082 ; Switch in ROM
lda COLOR ; Save current drawing color
pha
ldx MIX
ldy MAXY,x ; Max Y depends on 4 lines of text
jsr CLRSC2
pla
sta COLOR ; Restore current drawing color
bit $C080 ; Switch in LC bank 2 for R/O
rts
bit $C082 ; Switch in ROM
lda COLOR ; Save current drawing color
pha
ldx MIX
ldy MAXY,x ; Max Y depends on 4 lines of text
jsr CLRSC2
pla
sta COLOR ; Restore current drawing color
bit $C080 ; Switch in LC bank 2 for R/O
rts
; SETCOLOR: Set the drawing color (in A). The new color is already checked
; to be in a valid range (0..maxcolor-1).
; Must set an error code: NO (will only be called if color ok)
SETCOLOR:
bit $C082 ; Switch in ROM
tax
lda TGI2COL,x
jsr SETCOL
bit $C080 ; Switch in LC bank 2 for R/O
rts
bit $C082 ; Switch in ROM
tax
lda TGI2COL,x
jsr SETCOL
bit $C080 ; Switch in LC bank 2 for R/O
rts
; CONTROL: Platform/driver specific entry point.
; Must set an error code: YES
CONTROL:
; Check data msb and code to be 0
ora ptr1+1
bne err
; Check data msb and code to be 0
ora ptr1+1
bne err
; Check data lsb to be [0..1]
lda ptr1
cmp #1+1
bcs err
bit $C082 ; Switch in ROM
; Check data lsb to be [0..1]
lda ptr1
cmp #1+1
bcs err
bit $C082 ; Switch in ROM
; Switch 4 lines of text
tax
.assert MIXCLR + 1 = MIXSET, error
lda MIXCLR,x ; No BIT absolute,X available
; Switch 4 lines of text
tax
.assert MIXCLR + 1 = MIXSET, error
lda MIXCLR,x ; No BIT absolute,X available
; Save current switch setting
txa
sta MIX
bne text
; Save current switch setting
txa
sta MIX
bne text
; Clear 8 lines of graphics
lda COLOR ; Save current drawing color
pha
lda #39 ; Rightmost column
sta H2
ldx #40 ; First line
: txa
ldy #$00 ; Leftmost column
sty COLOR ; Black
jsr HLINE ; Preserves X
inx
cpx #47+1 ; Last line
bcc :-
pla
sta COLOR ; Restore current drawing color
bcs :+ ; Branch always
; Clear 8 lines of graphics
lda COLOR ; Save current drawing color
pha
lda #39 ; Rightmost column
sta H2
ldx #40 ; First line
: txa
ldy #$00 ; Leftmost column
sty COLOR ; Black
jsr HLINE ; Preserves X
inx
cpx #47+1 ; Last line
bcc :-
pla
sta COLOR ; Restore current drawing color
bcs :+ ; Branch always
; Clear 4 lines of text
text: jsr HOME
: bit $C080 ; Switch in LC bank 2 for R/O
; Clear 4 lines of text
text: jsr HOME
: bit $C080 ; Switch in LC bank 2 for R/O
; Done, reset the error code
lda #TGI_ERR_OK
beq :+ ; Branch always
; Done, reset the error code
lda #TGI_ERR_OK
beq :+ ; Branch always
; Done, set the error code
err: lda #TGI_ERR_INV_ARG
: sta ERROR
rts
; Done, set the error code
err: lda #TGI_ERR_INV_ARG
: sta ERROR
rts
; SETPALETTE: Set the palette (not available with all drivers/hardware).
; A pointer to the palette is passed in ptr1. Must set an error if palettes
; are not supported
; Must set an error code: YES
SETPALETTE:
lda #TGI_ERR_INV_FUNC
sta ERROR
rts
lda #TGI_ERR_INV_FUNC
sta ERROR
rts
; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
; set the palette should return the default palette here, so there's no
; way for this function to fail.
; Must set an error code: NO
GETPALETTE:
; Fall through
; Fall through
; GETDEFPALETTE: Return the default palette for the driver in A/X. All
; drivers should return something reasonable here, even drivers that don't
@@ -285,63 +285,63 @@ GETPALETTE:
; of the (not changeable) palette.
; Must set an error code: NO (all drivers must have a default palette)
GETDEFPALETTE:
lda #<DEFPALETTE
ldx #>DEFPALETTE
rts
lda #<DEFPALETTE
ldx #>DEFPALETTE
rts
; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
; color. The coordinates passed to this function are never outside the
; visible screen area, so there is no need for clipping inside this function.
; Must set an error code: NO
SETPIXEL:
bit $C082 ; Switch in ROM
ldy X1
lda Y1
jsr PLOT
bit $C080 ; Switch in LC bank 2 for R/O
rts
bit $C082 ; Switch in ROM
ldy X1
lda Y1
jsr PLOT
bit $C080 ; Switch in LC bank 2 for R/O
rts
; GETPIXEL: Read the color value of a pixel and return it in A/X. The
; coordinates passed to this function are never outside the visible screen
; area, so there is no need for clipping inside this function.
GETPIXEL:
bit $C082 ; Switch in ROM
ldy X1
lda Y1
jsr SCRN
tax
lda COL2TGI,x
ldx #$00
bit $C080 ; Switch in LC bank 2 for R/O
rts
bit $C082 ; Switch in ROM
ldy X1
lda Y1
jsr SCRN
tax
lda COL2TGI,x
ldx #$00
bit $C080 ; Switch in LC bank 2 for R/O
rts
; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
; Contrary to most other functions, the graphics kernel will sort and clip
; the coordinates before calling the driver, so on entry the following
; conditions are valid:
; X1 <= X2
; Y1 <= Y2
; (X1 >= 0) && (X1 < XRES)
; (X2 >= 0) && (X2 < XRES)
; (Y1 >= 0) && (Y1 < YRES)
; (Y2 >= 0) && (Y2 < YRES)
; X1 <= X2
; Y1 <= Y2
; (X1 >= 0) && (X1 < XRES)
; (X2 >= 0) && (X2 < XRES)
; (Y1 >= 0) && (Y1 < YRES)
; (Y2 >= 0) && (Y2 < YRES)
; Must set an error code: NO
BAR:
bit $C082 ; Switch in ROM
lda X2
sta H2
inc Y2
ldx Y1
: txa
ldy X1
jsr HLINE ; Preserves X
inx
cpx Y2
bcc :-
bit $C080 ; Switch in LC bank 2 for R/O
rts
bit $C082 ; Switch in ROM
lda X2
sta H2
inc Y2
ldx Y1
: txa
ldy X1
jsr HLINE ; Preserves X
inx
cpx Y2
bcc :-
bit $C080 ; Switch in LC bank 2 for R/O
rts
; ------------------------------------------------------------------------
.include "../../tgi/tgidrv_line.inc"
.include "../../tgi/tgidrv_line.inc"
+3 -3
View File
@@ -2,7 +2,7 @@
; Target-specific black & white values for use by the target-shared TGI kernel
;
.include "tgi-kernel.inc"
.include "tgi-kernel.inc"
.export tgi_color_black:zp = $00
.export tgi_color_white:zp = $03
.export tgi_color_black:zp = $00
.export tgi_color_white:zp = $03
+5 -5
View File
@@ -6,16 +6,16 @@
; const void tgi_static_stddrv[];
;
.export _tgi_static_stddrv
.ifdef __APPLE2ENH__
.import _a2e_hi_tgi
.export _tgi_static_stddrv
.ifdef __APPLE2ENH__
.import _a2e_hi_tgi
.else
.import _a2_hi_tgi
.import _a2_hi_tgi
.endif
.rodata
.ifdef __APPLE2ENH__
.ifdef __APPLE2ENH__
_tgi_static_stddrv := _a2e_hi_tgi
.else
_tgi_static_stddrv := _a2_hi_tgi
+4 -4
View File
@@ -6,13 +6,13 @@
; const char tgi_stddrv[];
;
.export _tgi_stddrv
.export _tgi_stddrv
.rodata
_tgi_stddrv:
.ifdef __APPLE2ENH__
.asciiz "A2E.HI.TGI"
.ifdef __APPLE2ENH__
.asciiz "A2E.HI.TGI"
.else
.asciiz "A2.HI.TGI"
.asciiz "A2.HI.TGI"
.endif
+1 -1
View File
@@ -3,7 +3,7 @@
; /* Convert a target specific character to ascii */
;
.export _toascii
.export _toascii
_toascii:
ldx #$00
+1 -1
View File
@@ -5,7 +5,7 @@
;
.ifdef __APPLE2ENH__
.export _videomode
.export _videomode
.import COUT
.include "apple2.inc"
+9 -9
View File
@@ -4,17 +4,17 @@
; VTABZ routine
;
.export VTABZ
.export VTABZ
.include "apple2.inc"
.include "apple2.inc"
.segment "LOWCODE"
.segment "LOWCODE"
VTABZ:
; Switch in ROM and call VTABZ
bit $C082
jsr $FC24 ; Generate text base address
; Switch in ROM and call VTABZ
bit $C082
jsr $FC24 ; Generate text base address
; Switch in LC bank 2 and return
bit $C080
rts
; Switch in LC bank 2 and return
bit $C080
rts
+3 -3
View File
@@ -4,11 +4,11 @@
; unsigned char wherex (void);
;
.export _wherex
.export _wherex
.include "apple2.inc"
.include "apple2.inc"
_wherex:
lda CH
lda CH
ldx #$00
rts
+4 -4
View File
@@ -4,13 +4,13 @@
; unsigned char wherey (void);
;
.export _wherey
.export _wherey
.include "apple2.inc"
.include "apple2.inc"
_wherey:
lda CV
lda CV
sec
sbc WNDTOP
sbc WNDTOP
ldx #$00
rts
+59 -59
View File
@@ -4,44 +4,44 @@
; int __fastcall__ write (int fd, const void* buf, unsigned count);
;
.export _write
.import rwprolog, rwcommon, rwepilog
.import COUT
.export _write
.import rwprolog, rwcommon, rwepilog
.import COUT
.include "zeropage.inc"
.include "errno.inc"
.include "fcntl.inc"
.include "mli.inc"
.include "filedes.inc"
.include "zeropage.inc"
.include "errno.inc"
.include "fcntl.inc"
.include "mli.inc"
.include "filedes.inc"
_write:
; Get parameters
jsr rwprolog
bcs errno
tax ; Save fd
jsr rwprolog
bcs errno
tax ; Save fd
; Check for write access
lda fdtab + FD::FLAGS,y
and #O_WRONLY
beq einval
lda fdtab + FD::FLAGS,y
and #O_WRONLY
beq einval
; Check for device
txa ; Restore fd
bmi device
txa ; Restore fd
bmi device
; Check for append flag
lda fdtab + FD::FLAGS,y
and #O_APPEND
beq write
; Check for append flag
lda fdtab + FD::FLAGS,y
and #O_APPEND
beq write
; Set fd
stx mliparam + MLI::EOF::REF_NUM
stx mliparam + MLI::EOF::REF_NUM
; Get file size
lda #GET_EOF_CALL
ldx #EOF_COUNT
jsr callmli
bcs oserr
lda #GET_EOF_CALL
ldx #EOF_COUNT
jsr callmli
bcs oserr
; REF_NUM already set
.assert MLI::MARK::REF_NUM = MLI::EOF::REF_NUM, error
@@ -50,65 +50,65 @@ _write:
.assert MLI::MARK::POSITION = MLI::EOF::EOF, error
; Set file pointer
lda #SET_MARK_CALL
ldx #MARK_COUNT
jsr callmli
bcs oserr
lda #SET_MARK_CALL
ldx #MARK_COUNT
jsr callmli
bcs oserr
; Do write
write: lda fdtab + FD::REF_NUM,y
ldy #WRITE_CALL
jmp rwcommon
write: lda fdtab + FD::REF_NUM,y
ldy #WRITE_CALL
jmp rwcommon
; Save count for epilog
device: ldx ptr2
lda ptr2+1
stx mliparam + MLI::RW::TRANS_COUNT
sta mliparam + MLI::RW::TRANS_COUNT+1
device: ldx ptr2
lda ptr2+1
stx mliparam + MLI::RW::TRANS_COUNT
sta mliparam + MLI::RW::TRANS_COUNT+1
; Check for zero count
ora ptr2
beq done
ora ptr2
beq done
; Get char from buf
ldy #$00
next: lda (ptr1),y
ldy #$00
next: lda (ptr1),y
; Replace '\n' with '\r'
cmp #$0A
bne :+
lda #$0D
cmp #$0A
bne :+
lda #$0D
; Set hi bit and write to device
: ora #$80
.ifndef __APPLE2ENH__
cmp #$E0 ; Test for lowercase
bcc output
and #$DF ; Convert to uppercase
: ora #$80
.ifndef __APPLE2ENH__
cmp #$E0 ; Test for lowercase
bcc output
and #$DF ; Convert to uppercase
.endif
output: jsr COUT ; Preserves X and Y
output: jsr COUT ; Preserves X and Y
; Increment pointer
iny
bne :+
inc ptr1+1
bne :+
inc ptr1+1
; Decrement count
: dex
bne next
dec ptr2+1
bpl next
bne next
dec ptr2+1
bpl next
; Return success
done: lda #$00
jmp rwepilog
done: lda #$00
jmp rwepilog
; Load errno code
einval: lda #EINVAL
einval: lda #EINVAL
; Set __errno
errno: jmp __directerrno
errno: jmp __directerrno
; Set __oserror
oserr: jmp __mappederrno
oserr: jmp __mappederrno