;FileBox wersja alfa

        .local fm

        .zpvar ptr1 .word
        .zpvar ptr2 .word
        .zpvar ptr3 .word
        .zpvar ptr4 .word
        .zpvar gpr1 .byte
        .zpvar gpr2 .byte

device  org     *+1
devno   org     *+1

fname   org     *+33 ;3+29+EOL
dname   org     *+16

dirbufptr       org *+2
dirbuflen       org *+2

drive_change_number    .byte 0
drive_change_device    .byte 0

        .endl

INTD    equ     254
INTEOL  equ     255

FileBoxInit .proc
        ldx     ZIOCB
        lda     HATABS,x
        sta     fm.device
        lda     ZIOCB+1
        ora     #'0'
        sta     fm.devno
        rts

        .endp

FileBoxExecute .proc (.word defextptr .word fm.dirbufptr .word fm.dirbuflen) .var

        ;narysuj okno fileboxa
        WinCreate #3 #2 #33 #20

        ;narysuj dodatki do okna
        jsr     DrawBox

loop
        ;odczyt katalogu dysku
        jsr     FormatDirname

        ;wypisz nazwę dysku
        jsr     PrintDevName

        ;odczytaj katalog
        ReadDirectory #fm.dname fm.dirbufptr fm.dirbuflen
        bpl     printdir
        lda     fm.drive_change_number
        jeq     device_select ;fbexit
        sta     fm.devno
        mva     fm.drive_change_device fm.device
        mva     #0 fm.drive_change_number
        jmp     loop

printdir
        ;wypisz ilość wolnych sektorów
        mwa     WinData.winptr fm.ptr3
        adw     fm.ptr3 #(18*40+1)
        PutText ReadDirectory.bufptr fm.ptr3 #31 #$9b #SRC_ATASCII+DST_INTERNAL

        ;wypis listy plików, przygotowanie
        lda     #0
        sta     fileindex ;0...31
        sta     column    ;0...255

wypisz
        mwa     WinData.winptr fm.ptr3
        adw     fm.ptr3 #41
        mwa     ReadDirectory.fcount fm.ptr1
        ldx     #0

        .test   .word fm.ptr1 = #0
        ;wypisz "no files"
        ldy     #14
nf1     lda     nft,y
        sta     (fm.ptr3),y
        dey
        bpl     nf1
        sty     lfileindex ;zaznacz "jest 0 plików"
        iny
        sty     fm.gpr1
        jeq     pt2
nft     .byte   "no files       "
        .endt

        ;indeks ostatniego wpisu
        ;lcolumn = fcount/16 - (fcount/16 == 0 ? 0 : 1)
        ;lfileindex = fcount&15 + (fcount/16 == 0 ? 0 : 16)
        dew     fm.ptr1
        lda     fm.ptr1
        and     #15
        sta     lfileindex
        lda     fm.ptr1
        lsr     fm.ptr1+1
        ror
        lsr     fm.ptr1+1
        ror
        lsr     fm.ptr1+1
        ror
        lsr     fm.ptr1+1
        ror
        sta     lcolumn
        beq     iow1
        dec     lcolumn
        lda     lfileindex
        add     #16
        sta     lfileindex
iow1    lda     #32
        ldy     column
        cpy     lcolumn
        bne     iow2
        lda     lfileindex
        adc     #0
iow2    sta     fm.gpr1

        ;fm.ptr2 = (reclen * column * 16) + (dirbufptr) + 2
        ;wskaźnik do bufora directory dla pierwszego wyświetlanego pliku
        Mul8    column ReadDirectory.reclen
        mwa     Mul8.result fm.ptr2
        asl     fm.ptr2
        rol     fm.ptr2+1
        asl     fm.ptr2
        rol     fm.ptr2+1
        asl     fm.ptr2
        rol     fm.ptr2+1
        asl     fm.ptr2
        rol     fm.ptr2+1
        adw     fm.ptr2 fm.dirbufptr
        adw     fm.ptr2 #2

        ;wypisz listę plików (max 32 w dwóch kolumnach po 16 plików)
        ;dopełnij ją znakami " " gdy jest mniej niż 32 pliki.
pt3     ldy     #14
pt4     lda     #0
        cpx     fm.gpr1
        jcc     pt6
pt7     sta     (fm.ptr3),y
        dey
        bpl     pt7
        jmi     pt2
pt6     cpx     fileindex
        jne     pt9
        mwa     fm.ptr2 fm.ptr4
        lda     #$80
pt9     sta     fm.gpr2
pt8     lda     (fm.ptr2),y
        Atascii2Int @
        eor     fm.gpr2
        sta     (fm.ptr3),y
        dey
        bpl     pt8
        adw     fm.ptr2 ReadDirectory.reclen
pt2     adw     fm.ptr3 #40
        inx
        cpx     #32
        jeq     pt1
        cpx     #16
        jne     pt3
        sbw     fm.ptr3 #(40*16-16)
        jmp     pt3
pt1

        ;klawiatura
keyboard
        mva     #0 fm.drive_change_number
        GetKey
        cpy     #$2c ;TAB
        jeq     fn_edit
        cpy     #$1c
        jne     kb2
        ldy     #255
        jmi     fbexit
kb2     lda     lfileindex
        bmi     kb1
        ;tylko jeżeli co najmniej 1 plik
        cpy     #$06 ;lewo
        jeq     left
        cpy     #$07 ;prawo
        jeq     right
        cpy     #$0e ;góra
        jeq     up
        cpy     #$0f ;dół
        jeq     down
        cpy     #$0c ;return
        jeq     return
kb1     lda     (KEYDEF),y
        cmp     #'D'
        jeq     device_select
        cmp     #'d'
        jeq     device_select
        cmp     #'0'
        bcc     no_drive
        cmp     #'9'+1
        bcs     no_drive
        mvx     fm.device fm.drive_change_device
try_other_devno
        mvx     fm.devno fm.drive_change_number
        sta     fm.devno
        jmp     loop
no_drive
        jmp     keyboard

device_select
        mva     fm.device dsdevice
        mva     fm.devno dsdevno
        WinCreate #4 #3 #21 #8
dsloop  mwa     WinData.winptr fm.ptr1
        adw     fm.ptr1 #41
        PutText #dst1 fm.ptr1 #0 #INTD #SRC_INTERNAL+DST_INTERNAL
        ldx     #0
ds3     lda     HATABS,x
        sne
        lda     #' '
        cmp     dsdevice
        sne
        ora     #$80
        PutChar @ #0 #SRC_ATASCII+DST_INTERNAL
        :3 inx
        cpx     #11*3
        bcc     ds3
        adw     fm.ptr1 #120
        PutText #dst2 fm.ptr1 #0 #INTD #SRC_INTERNAL+DST_INTERNAL
        ldx     #0
ds2     txa
        ora     #'0'
        cmp     dsdevno
        sne
        ora     #$80
        PutChar @ #0 #SRC_ATASCII+DST_INTERNAL
        inx
        cpx     #10
        jcc     ds2
        adw     fm.ptr1 #80
        PutText #dst3 fm.ptr1 #0 #INTD #SRC_INTERNAL+DST_INTERNAL
dsl1    GetKey
        cpy     #$0c ;return
        jeq     dselected
        cpy     #$1c
        jeq     dresign
        cmp     #'0'
        bcc     ds_nodig
        cmp     #'9'+1
        jcs     ds_nodig
        sta     dsdevno
        jmp     dsloop
ds_nodig
        ldx   #0
dschk1  and     #$7f-$20
        cmp     HATABS,x
        jeq     ds_devsel
        :3 inx
        cpx     #11*3
        jcc     dschk1
        jmp     dsl1
ds_devsel
        sta     dsdevice
        jmp     dsloop
dselected
        WinDestroy
        mva     fm.device fm.drive_change_device
        lda     dsdevice
        sta     fm.device
        lda     dsdevno
        jmp     try_other_devno
dresign WinDestroy
        jmp     keyboard

dsdevice .byte 0
dsdevno .byte 0
dst1    .byte   "Select device",INTEOL,INTEOL
        .byte   "HTABS: ",INTD
dst2    .byte   "DEVno: ",INTD
dst3    .byte   "Press RETURN or ESC",INTD

fn_edit jsr     DirnameCopy
fn_ed1  mwa     WinData.winptr fm.ptr1
        adw     fm.ptr1 #(18*40+1)
        PutText #fm.fname fm.ptr1 #31 #$9b #SRC_ATASCII+DST_INTERNAL
        GetText fm.ptr1 #31 #GT_UPPERCASE+GT_TABEXITS
        bne     fn_edit_nothing
        ;naciśnięto RETURN
        PutText fm.ptr1 #fm.fname #0 #0 #SRC_INTERNAL+DST_ATASCII
        PutCh   #$9b
        ldy     #0
        jeq     fbexit
fn_edit_nothing
        ;TAB lub ESC przy edycji nazwy
        ;php
        PutText ReadDirectory.bufptr fm.ptr1 #31 #$9b #SRC_ATASCII+DST_INTERNAL
        ;plp
        ;jmi     fbexit
        jmp     wypisz

return  jsr     DirnameCopy
        ldy     #0
ret2    lda     (fm.ptr4),y
        cmp     #' '
        jeq     ret1
        sta     fm.fname,x
        inx
        iny
        cpy     #8
        bcc     ret2
ret1    ldy     #8
        lda     (fm.ptr4),y
        cmp     #' '
        jeq     ret3
        lda     #'.'
ret4    sta     fm.fname,x
        inx
        cpy     #11
        bcs     ret3
        lda     (fm.ptr4),y
        iny
        cmp     #' '
        jne     ret4
ret3    lda     #$9b
        sta     fm.fname,x
        jmp     fn_ed1

left    lda     #16
decr    sub     fileindex
        bcc     lf2
        beq     lf4
        sbc     #1
        eor     #15
        sta     fileindex
        lda     column
        jeq     lf4
lf3     dec     column
        jmp     wypisz
lf2     eor     #$ff
        adc     #1
lf4     sta     fileindex
        jmp     wypisz

right   lda     #16
incr    add     fileindex
        cmp     #32
        jcc     ri1
        sbc     #16
        inc     column
ri1     sta     fileindex
        lda     column
        cmp     lcolumn
        jcc     wypisz
        jne     ri2
        lda     lfileindex
        cmp     fileindex
        jcs     wypisz
ri2     mva     lcolumn column
        mva     lfileindex fileindex
        jmp     wypisz

up      lda     #1
        jne     decr

down    lda     #1
        jne     incr

fbexit  tya
        pha
        WinDestroy
        pla
        tay
        rts

DrawBox mwa     WinData.winptr fm.ptr1
        adw     fm.ptr1 #(17*40)
        ldy     WinData.width
        dey
        mva     #$44 (fm.ptr1),y
        dey
        lda     #$52
db1     sta     (fm.ptr1),y
        dey
        bne     db1
        mva     #$41 (fm.ptr1),y
        rts

PrintDevName
        mwa     WinData.winptr fm.ptr1
        ldy     #1
        mva     #$44 (fm.ptr1),y
        iny
        ldx     #0
pdn3    lda     fm.dname,x
        bmi     pdn2
        Atascii2Int @
        sta     (fm.ptr1),y
        iny
        inx
        bne     pdn3
pdn2    mva     #$41 (fm.ptr1),y
        iny
        lda     #$52
        sta     (fm.ptr1),y
        rts

FormatDirname
        ldx     #1
        lda     fm.device
        sta     fm.dname
        lda     fm.devno
        sta     fm.dname+1
        cmp     #'1'
        bcc     fdn1
        cmp     #'9'+1
        bcs     fdn1
        inx
fdn1    lda     #':'
        sta     fm.dname,x
        mwa     defextptr fm.ptr2
        lda     fm.ptr2
        ora     fm.ptr2+1
        jne     ncopy
        lda     #'*'
        sta     fm.dname+1,x
        sta     fm.dname+3,x
        lda     #'.'
        sta     fm.dname+2,x
peol    lda     #$9b
        sta     fm.dname+4,x
        rts
ncopy   ldy     #255
nc1     iny
        inx
        cpx     #15
        bcs     peol
        lda     (fm.ptr2),y
        sta     fm.dname,x
        bpl     nc1
        rts

DirnameCopy
        ldx     #0
dnc1    lda     fm.dname,x
        sta     fm.fname,x
        inx
        cmp     #':'
        jne     dnc1
        lda     #$9b
        sta     fm.fname,x
        rts

defextptr       .word   0
fileindex       .byte   0
column          .byte   0
lfileindex      .byte   0
lcolumn         .byte   0

        .endp



;-----------------------------------------------------------
;MINI PODSYSTEM IO, dla jednego pliku



FileOpen .proc (.word fname .byte aux1) .var

        ldx     channel
        bmi     l2
        ldy     #255
        jmp     ErrorBox
l2      ldx     #0
l1      lda     ICHID,x
        cmp     #$ff
        beq     found
        txa
        clc
        adc     #$10
        tax
        bpl     l1
        ldy     #-95
        sty     status
        jmp     ErrorBox
found   mwa     fname ICBAL,x
        mva     aux1 ICAX1,x
        mva     #CIO_open ICCOM,x
        mwa     #0xff ICBLL,x
        mva     #0 ICAX2,x
        jsr     CIOMAIN
        sty     status
        stx     channel
        jmp     ErrorBox

fname   .word   0
aux1    .byte   CIO_read
channel .byte   0xff
status  .byte   1

        .endp

SetupTransfer .proc (.word ptr .byte mode) .var

        ldy     FileOpen.status
        spl
        rts
        ldx     FileOpen.channel
        spl
        rts
        mva     mode ICCOM,x
        tya
        rts

ptr     .word   0
mode    .byte   0

        .endp

NextTransfer .proc (.word length) .var

        ldy     FileOpen.status
        spl
        rts
        ldx     FileOpen.channel
        spl
        rts
        mwa     SetupTransfer.ptr ICBAL,x
        mwa     length ICBLL,x
        jsr     CIOMAIN
        jsr     ErrorBox
        sty     FileOpen.status
        adw     SetupTransfer.ptr ICBLL,x
        mwa     ICBLL,x length
        tya
        rts

length  .word   0

        .endp

FileClose .proc

        ldx     FileOpen.channel
        jmi     fc
        mva     #0xff FileOpen.channel
        mva     #CIO_close ICCOM,x
        jsr     CIOMAIN
fc      lda     #1
        ldy     FileOpen.status
        sta     FileOpen.status
        rts

        .endp


ErrorBox .proc

        tya
        smi
        rts
        cpy     #136
        sne
        rts
        sty     ebx+1
        pha
        txa
        pha

        ldx     #"0"-1
ebx     lda     #0
ebx1    inx
        sub     #100
        bcs     ebx1
        adc     #100
        stx     ertxt+9
        ldx     #"0"-1
ebx2    inx
        sub     #10
        bcs     ebx2
        adc     #10
        stx     ertxt+10
        add     #"0"
        sta     ertxt+11

        mwa     PutChar.adr cptr
        WinCreate #11 #8 #16 #5
        mwa     WinData.winptr ptr
        adw     ptr #82
        PutText #ertxt ptr #0 #INTD #SRC_INTERNAL+DST_INTERNAL
        GetKey
        WinDestroy
        mwa     cptr PutChar.adr

        pla
        tax
        pla
        tay
        rts

ertxt   .byte   "IO Error 140",INTD
ptr     .word   0
cptr    .word   0

        .endp

ReadDirectory .proc (.word maskptr .word bufptr .word buflen) .var

        FileOpen maskptr #CIO_dir
        jmi     err
        SetupTransfer bufptr #CIO_gettext
        jmi     err
        mwa     #0 fcount
        sta     reclen
loop    .test .word buflen >= #48
        mwa     SetupTransfer.ptr bufptr
        sbw     bufptr NextTransfer.length
        NextTransfer #32
        jpl     record
        cpy     #136
        jne     err
        dew     fcount
        jmp     fin
record  inw     fcount
        sbw     buflen NextTransfer.length
        lda     reclen
        jne     loop
        mva     NextTransfer.length reclen
        jmp     loop
        .endt
koniec  ;pełny bufor
        ;szukaj ciągu z ilością wolnych sektorów
l2      mwa     SetupTransfer.ptr bufptr
        sbw     bufptr NextTransfer.length
        NextTransfer #32
        jpl     record1
        cpy     #136
        jne     err
fin     FileClose
        ldy     #1
        rts
record1 sbw     SetupTransfer.ptr NextTransfer.length
        jmp     l2
err     FileClose
        mwa     #0 fcount
        mwa     #0 bufptr
        tya
        rts

fcount  .word   0 ;ile plików odczytała procedura (0 gdy błąd), param. wyjściowy
maskptr .word   0 ;wskaźnik na ciąg np. "D1:*.*", parametr wejściowy
bufptr  .word   0 ;wskaźnik na ciąg "xxxx Free sectors", param. wyjściowy
buflen  .word   0 ;długość bufora, param. wejściowy
reclen  .word   0 ;długość ciągu ATASCII dla jednego pliku wraz z EOL, 0 gdy błąd, param. wyjściowy

        .endp

;-----------------------------------------------------------
;Prosty Podsystem Okienkowy


WinData .proc

bufptr  .word   0 ;wskaźnik do bufora z danymi o okienku i ekranem "pod oknem"
winptr  .word   0 ;wskaźnik na lewy górny róg okna
windows .byte   0 ;ilość otwartych okienek
width   .byte   0 ;szerokość aktywnego okienka (z ramkami)
height  .byte   0 ;wysokość aktywnego okienka (z ramkami)

        .endp

WinSetup .proc (.word ptr) .var

ws      lda     WinData.bufptr
        ora     WinData.bufptr+1
        seq
        rts
        sta     WinData.windows
        mwa     ptr WinData.bufptr
        rts

ptr     .word   0

        .endp

WinCreate .proc (.byte xpos .byte ypos .byte WinData.width .byte WinData.height) .var

        mwa     fm.ptr1 sptr1
        mwa     fm.ptr2 sptr2
        Mul8    #40 ypos
        lda     xpos
        clc
        adc     Mul8.rlo
        sta     fm.ptr1
        lda     #0
        adc     Mul8.rhi
        sta     fm.ptr1+1
        adw     fm.ptr1 SAVMSC
        mwa     WinData.bufptr fm.ptr2
        lda     WinData.windows
        jeq     wc9
        ldy     #4
        lda     (fm.ptr2),y
        sta     xpos
        iny
        lda     (fm.ptr2),y
        Mul8    @ xpos
        mwa     Mul8.result fm.ptr2
        adw     fm.ptr2 #6
        adw     fm.ptr2 WinData.bufptr
wc9     ldy     #0
        mva     WinData.bufptr (fm.ptr2),y
        iny
        mva     WinData.bufptr+1 (fm.ptr2),y
        mwa     fm.ptr2 WinData.bufptr
        iny
        mva     fm.ptr1 (fm.ptr2),y
        sta     WinData.winptr
        iny
        mva     fm.ptr1+1 (fm.ptr2),y
        sta     WinData.winptr+1
        iny
        mva     WinData.width (fm.ptr2),y
        sta     xpos
        iny
        mva     WinData.height (fm.ptr2),y
        sta     ypos
        adw     fm.ptr2 #6
        dec     xpos
wc2     ldy     xpos
wc1     lda     (fm.ptr1),y
        sta     (fm.ptr2),y
        lda     #0
        ldx     ypos
        cpy     #0
        sne
        ora     #1
        cpy     xpos
        sne
        ora     #2
        cpx     #1
        sne
        ora     #4
        cpx     WinData.height
        sne
        ora     #8
        tax
        lda     rtab,x
        sta     (fm.ptr1),y
        dey
        jpl     wc1
        adw     fm.ptr1 #40
        lda     xpos
        sec
        adc     fm.ptr2
        sta     fm.ptr2
        scc
        inc     fm.ptr2+1
        dec     ypos
        jne     wc2
        inc     WinData.windows
        mwa     sptr1 fm.ptr1
        mwa     sptr2 fm.ptr2
        rts

;znaki ramki
LGR     equ     $51 ;lewy górny róg
GD      equ     $52 ;góra i dół
PGR     equ     $45 ;prawy górny róg
LP      equ     $7c ;lewy i prawy
LDR     equ     $5a ;lewy dolny róg
PDR     equ     $43 ;prawy dolny róg
SRODEK  equ     $0  ;środek okna

rtab    .byte   SRODEK,LP,LP,SRODEK
        .byte   GD,LDR,PDR,SRODEK
        .byte   GD,LGR,PGR,SRODEK
        .byte   SRODEK,SRODEK,SRODEK,SRODEK

xpos    .byte   0
ypos    .byte   0
sptr1   .word   0
sptr2   .word   0

        .endp

WinDestroy .proc

        ldx     WinData.windows
        sne
        rts
        mwa     fm.ptr1 WinCreate.sptr1
        mwa     fm.ptr2 WinCreate.sptr2
        mwa     WinData.bufptr fm.ptr1
        mwa     WinData.winptr fm.ptr2
        ldy     #0
        mva     (fm.ptr1),y WinData.bufptr
        iny
        mva     (fm.ptr1),y WinData.bufptr+1
        adw     fm.ptr1 #6
        ldx     WinData.height
wd2     ldy     WinData.width
        dey
wd1     mva     (fm.ptr1),y (fm.ptr2),y
        dey
        bpl     wd1
        lda     WinData.width
        clc
        adc     fm.ptr1
        sta     fm.ptr1
        scc
        inc     fm.ptr1+1
        adw     fm.ptr2 #40
        dex
        bne     wd2
        mwa     WinData.bufptr fm.ptr1
        ldy     #2
        mva     (fm.ptr1),y WinData.winptr
        iny
        mva     (fm.ptr1),y WinData.winptr+1
        iny
        mva     (fm.ptr1),y WinData.width
        iny
        mva     (fm.ptr1),y WinData.height
        dec     WinData.windows
        mwa     WinCreate.sptr1 fm.ptr1
        mwa     WinCreate.sptr2 fm.ptr2
        rts

        .endp
;-----------------------------------------------------------
;Inne procedury usługowe

;wyświetlenie tekstu Atascii / Internal z dopełnieniem spacjami do max 39 znaków

;len - długość maksymalna tekstu
;limiter - znak końca (np. #$9b - EOL dla ATASCII)

        SRC_ATASCII = 0
        SRC_INTERNAL = 1
        SRC_ASCII = 2
        DST_ATASCII = 0
        DST_INTERNAL = 4
        DST_ASCII = 8

PutText .proc (.word txtptr .word scrptr .byte len .byte limiter .byte CharConv.mode) .var

        mwa     fm.ptr1 sptr1
        mwa     fm.ptr2 sptr2
        mwa     txtptr fm.ptr1
        mwa     scrptr fm.ptr2

        lda     limiter
        sta     limiter1
        inc     limiter1

        .test .word fm.ptr2 = #0
        mwa     PutChar.adr fm.ptr2
        .endt

wf0     ldy     #0
wf2     lda     len
        jeq     wf21
        cpy     len
        jcs     wf41
wf21    lda     (fm.ptr1),y
        cmp     limiter
        beq     wf1
        cmp     limiter1
        beq     wf31
        CharConv @
        sta     (fm.ptr2),y
        iny
        bne     wf2
wf1     lda     len
        jeq     wf41
        mva     CharConv.mode msv+1
        and     #~(SRC_ATASCII+SRC_ASCII)
        ora     #SRC_INTERNAL
        sta     CharConv.mode
        lda     #" "
        CharConv @
        pha
msv     lda     #0
        sta     CharConv.mode
        pla
wf4     sta     (fm.ptr2),y
        iny
        cpy     len
        jcc     wf4
wf41    tya
        clc
        adc     fm.ptr2
        sta     PutChar.adr
        lda     fm.ptr2+1
        adc     #0
        sta     PutChar.adr+1
        mwa     sptr1 fm.ptr1
        mwa     sptr2 fm.ptr2
        rts
wf31    adw     fm.ptr2 #40
        iny
        tya
        add     fm.ptr1
        sta     fm.ptr1
        jcc     wf0
        inc     fm.ptr1+1
        jcs     wf0

len     .byte   0
modes   .byte   0
limiter .byte   0
limiter1 .byte   0
txtptr  .word   0
scrptr  .word   0
sptr1   .word   0
sptr2   .word   0

        .endp

PutCh   .proc (.byte a) .reg

        PutChar @ #0 #SRC_INTERNAL+DST_INTERNAL
        rts

        .endp

PutChar .proc (.byte char .word scrptr .byte CharConv.mode) .var

        .test .word scrptr <> #0
        mwa     scrptr adr
        .endt
        CharConv char
adr     equ     *+1
        sta     $ffff
        inw     adr
        rts

scrptr  .word   0
char    .byte   0

        .endp

SetCursor .proc (.word scrptr .byte cx .byte cy) .var

        .test .word scrptr = #0
        mwa     WinData.winptr scrptr
        .endt
        Mul8    cy #40
        mwa     Mul8.result PutChar.adr
        adw     PutChar.adr scrptr
        adw     PutChar.adr cx
        rts

cy      .byte   0
cx      .byte   0
        .byte   0
scrptr  .word   0

        .endp


CharConvSetup .proc (.byte CharConv.mode) .var

        rts

        .endp

CharConv .proc (.byte a) .reg

        pha
        lda     mode
        and     #3
        cmp     #SRC_INTERNAL
        jeq     cc3
        cmp     #SRC_ATASCII
        jeq     cc2
        ;ascii -> internal
        pla
        Ascii2Int @
        jmp     cc1
cc2     ;atascii -> internal
        pla
        Atascii2Int @
cc1     ;tutaj mamy char INTERNAL
        pha
cc3     lda     mode
        and     #0x0c
        cmp     #DST_INTERNAL
        jeq     mode_no_change
        cmp     #DST_ATASCII
        jeq     mode_atascii
mode_ascii
        pla
        Int2Ascii @
        rts
mode_atascii
        pla
        Int2Atascii @
        rts
mode_no_change
        pla
        rts

mode    .byte   SRC_ATASCII+DST_INTERNAL

        .endp

;wpisanie wiersza tekstu, max 39 znaków

        GT_CLEAR = 1
        GT_SPACES = 2
        GT_UPPERCASE = 4
        GT_TABEXITS = 8

GetText .proc (.word scrptr .byte len .byte flags) .var

        ;flags 1 = kasuj wpisany tekst na początku
        ;      2 = spacje dopuszczalne
        ;len = 2...40 (1 do 39 znaków)
        ;maks długość = len-1 (bo 1 znak to kursor)

        mwa     fm.ptr2 sptr2
        jsr     gt
        mwa     sptr2 fm.ptr2
        tya
        rts

sptr2   .word   0

gt      lda     #2
        cmp     len
        bcc     gt2
        sta     len
gt2     lda     #40
        cmp     len
        bcs     gt1
        sta     len
gt1     .test .word scrptr = #0
        mwa     PutChar.adr scrptr
        .endt
        mwa     scrptr fm.ptr2
        ;kopiuj starą linię do bufora
        ldy     #0
gt3     lda     (fm.ptr2),y
        sta     lbuf,y
        iny
        cpy     len
        bcc     gt3
        ;wstępne kasowanie linii
        lda     flags
        and     #GT_CLEAR
        beq     szukaj
        ldy     len
        dey
        lda     #0
l1      sta     (fm.ptr2),y
        dey
        bpl     l1
        ;szukaj konca wpisanego juz tekstu
szukaj  dec     len
        ldy     #0
        ldx     #0xff
l2      lda     (fm.ptr2),y
        beq     l3
        tya
        tax
l3      iny
        cpy     len
        bcc     l2
        inc     len
        inx
        txa
        tay
        ;pętla edycji
l7      lda     #$80
        sta     (fm.ptr2),y
        ldx     #15
l6      lda     #255
        sta     KBCODES
l5      lda     KBCODES
        cmp     #255
        bne     l4
        lda     TIMER
        cmp     TIMER
        req
        dex
        bne     l5
        lda     (fm.ptr2),y
        eor     #$80
        sta     (fm.ptr2),y
        ldx     #10
        bne     l5
l4      lda     KBCODES
        cmp     #$1c  ;ESC
        jeq     esc
        cmp     #$0c  ;RETURN
        jeq     return
        cmp     #$34  ;BACKSPACE
        jeq     bkspace
        cmp     #$2c  ;TAB
        jne     znak
        lda     flags
        and     #GT_TABEXITS
        jeq     znak
        jne     tab
        ;znak
znak    iny
        cpy     len
        dey
        bcs     l6
        sty     hlp
        tay
        lda     (KEYDEF),y
        ldy     hlp
        cmp     #'a'
        jcc     a0
        cmp     #'z'+1
        jcs     a0
        sta     hlp
        lda     flags
        and     #GT_UPPERCASE
        jne     a01
        lda     hlp
        jne     valid
a01     lda     hlp
        add     #'A'-'a'
        jmp     valid
a0      cmp     #'A'
        jcc     a1
        cmp     #'Z'+1
        jcc     valid
a1      cmp     #'0'
        jcc     a2
        cmp     #'9'+1
        jcc     valid
a2      cmp     #'-'
        jeq     valid
        cmp     #'+'
        jeq     valid
        cmp     #'_'
        jeq     valid
        cmp     #':'
        jeq     valid
        cmp     #'.'
        jeq     valid
        cmp     #' '
        jne     l6
        lda     flags
        and     #GT_SPACES
        jeq     l6
        lda     #' '
valid   Atascii2Int @
        sta     (fm.ptr2),y
        iny
        jne     l7
tab     jsr     return
        ldy     #1
        rts
bkspace tya
        jeq     l6
        lda     #0
        sta     (fm.ptr2),y
        dey
        jpl     l7
esc     ;kopiuj starą linię z bufora na ekran
        ldy     #0
e1      lda     lbuf,y
        sta     (fm.ptr2),y
        iny
        cpy     len
        bcc     e1
        ldy     #255
        sty     KBCODES
        rts
return  lda     #0
        sta     (fm.ptr2),y
        ;iny
        sty     len
        ldy     #255
        sty     KBCODES
        tay
        rts

lbuf    org     *+40
scrptr  .word   0
flags   .byte   0
len     .byte   0
hlp     .byte   0

        .endp


Ascii2Int .proc (.byte a) .reg
        and     #$7f
        cmp     #$60
        scs
        sbc     #$1f
        rts
        .endp

Atascii2Int .proc (.byte a) .reg
        asl
        php
        cmp     #192
        bcs     ok
        sbc     #63
        bcs     ok
        adc     #192
ok      plp
        ror
        rts
        .endp

Int2Ascii .proc (.byte a) .reg
        and     #$7f
        cmp     #$60
        scs
        adc     #$20
        rts
        .endp

Int2Atascii .proc (.byte a) .reg
        asl
        php
        cmp     #192
        bcs     ok
        sbc     #127
        bcs     ok
        adc     #192
ok      plp
        ror
        rts
        .endp

Ascii2Atascii .proc (.byte a) .reg
        rts
        .endp

Atascii2Ascii .proc (.byte a) .reg
        rts
        .endp



;odczyt znaku z klawiatury
; wy: A = kod ATASCII, Y = kod klawiatury
GetKey  .proc

        mva     #$ff KBCODES
gk      ldy     KBCODES
        cpy     #$ff
        jeq     gk
        sta     KBCODES
        lda     (KEYDEF),y
        sty     keycode
        sta     atascii

        cmp     #'A'
        bcc     gk1
        cmp     #'Z'+1
        bcs     gk1
        add     #'a'-'A'

gk1     sta     atascii_lowercase
        lda     atascii
        rts

keycode .byte   0
atascii .byte   0
atascii_lowercase .byte 0

        .endp

Delay   .proc (.word frames) .var

dl1     lda     TIMER
        cmp     TIMER
        req
        lda     frames
        ora     frames+1
        jeq     dl2
        dew     frames
        jmp     dl1
dl2     rts
        
frames  .word   0

        .endp

;mnożenie 8x8 - autor ? - procedura pochodzi z pakietu MADS
; ACC*AUX -> ACC,EXT (low,hi) 16 bit result
Mul8    .proc (.byte acc,aux) .var

        lda    #0
        ldy    #$09
        clc
loop    ror
        ror    acc
        bcc    mul2
        clc    ;dec aux above to remove clc
        adc    aux
mul2    dey
        bne    loop
        sta    ext
        rts

aux     .byte   0
result  equ     *
rlo     equ     *
acc     .byte   0
rhi     equ     *
ext     .byte   0

        .endp

;putline makro i procedura

putl    .macro
        jmp     ex
tx      .byte   :1,$9b
ex      PutLine #tx
        .endm

PutLine .proc (.word yx) .reg

        stx     ICBAL
        sty     ICBAH
        mwa     #0xff ICBLL
        mva     #CIO_puttext ICCOM
        ldx     #0
        jmp     CIOMAIN

        .endp

OSPutCh .proc (.byte a) .reg

        tay
        lda     ICPTH
        pha
        lda     ICPTL
        pha
        ldx     #0
        tya
        rts

        .endp

phall   .macro
        sta     pa2+1
        php
        pha
        tya
        pha
        txa
        pha
pa2     lda     #0
        .endm

plall   .macro
        pla
        tax
        pla
        tay
        pla
        plp
        .endm

