;**********************************************************************;
;*               A T O M I C   M E M O R Y   E D I T O R              *;
;*--------------------------------------------------------------------*;
;*    doel           : Memory editor voor eprom programmer            *;
;*--------------------------------------------------------------------*;
;*    filenaam       : hexedit.asm                                    *;
;*    auteur         : Roland Leurs                                   *;
;*                     The Atomic Development Studio                  *;
;*    ontwikkeld     : sep 1996                                       *;
;*    laatste update :                                                *;
;*--------------------------------------------------------------------*;
;*    assembleren    : x6502 hexedit                                  *;
;**********************************************************************;

zp              equ     $80
mem_home        equ     $87
mwrk            equ     $88
work            equ     $90
menutxtkleur    equ     $00
tekstkleur      equ     $0e
prthex          equ     $f802
leesbyte        equ     $ffc5
zendbyte        equ     $ffc8
osbyte          equ     $ffc2
wrch            equ     $fff4
rdch            equ     $ffe3

                org     $9a00-16

header          .dw     header+16, main
                .dw     0,0,0,0,0,0

                include routines.inc
                include input.inc

main            ldy #7                  ;schakel naar scherm 7
                jsr screen
                ldx #<maintext1         ;zet (c) regel op scherm
                ldy #>maintext1
                jsr write
                jsr setsem              ;zet semafoor
                lda #28                 ;maak tekst window
                jsr $ffc8
                lda #0                  ;  0,23,79,0
                jsr $ffc8
                lda #23
                jsr $ffc8
                lda #79
                jsr $ffc8
                lda #0
                jsr $ffc8
                jsr clrsem              ;wis semafoor
                ldx #<maintext2         ;zet menubalk op scherm
                ldy #>maintext2
                jsr write
                kader 0,23,79,1,0,14    ;teken kader
                jsr memedit             ;voer programma uit
                ldy #0                  ;terug naar scherm 0
                jsr screen
                ldx #11                 ;herstel cursor
                ldy #12
                jsr cursor_def
                jsr cursor_on
                lda $1ffc               ;herstel schermkleur
                jsr colour
                rts                     ;einde programma

memedit         ldx #$00                ;beginadres van memory dump
                stx $81
                ldx #00
                stx $80
                lda #02                 ;zet bovenregel voor memory dump
                sta mwrk+5
                lda #23                 ;zet onderregel voor memory dump
                sta mwrk+6
                ldx #0                  ;zet cursor definitie
                ldy #12
                jsr cursor_def
                ldx #3                  ;cursor naar (3,mwrk+5)
                ldy mwrk+5
                jsr gotoxy
                sec                     ;zet carry voor berekening
                lda mwrk+6              ;bereken aantal gebruikte regels
                sbc mwrk+5
                sta mwrk+4              ;berg op in werkruimte
memedit0        jsr memdump             ;toon pagina op scherm
mem_cursor_home ldx #4                  ;cursor naar eerste regel
                stx mwrk                ;cursor positie opbergen
                ldy mwrk+5
                sty mwrk+1
                jsr gotoxy
mem_test_key    lda #$0E                ;lees toetsenbord met osbyte#0E
                jsr osbyte
                lsr a                   ;test of toets gedrukt is
                bcc mem_test_key        ;spring indien geen toets
                cpx #27                 ;escape gedrukt?
                beq memedit_exit        ;ja, dan naar einde van routine
                cpy #82                 ;insert gedrukt?
                beq memedit2            ;ja, spring
                cpy #72                 ;cursor up?
                beq mem_cur_up
                cpy #80                 ;cursor down?
                beq mem_cur_down
                cpy #75                 ;cursor left?
                beq mem_cur_left
                cpy #77                 ;cursor right?
                beq mem_cur_right
                cpy #81                 ;toets PGUP?
                beq mem_page_up         ;ja, spring
                cpy #73                 ;toets PGDN?
                bne mem_test_key        ;nee, dan ongeldige toets
mem_page_down   ldx mwrk+4              ;laadt aantal schermregels
mem_page_down1  sec                     ;zet carry voor berekening
                lda zp                  ;zet adrespointer 32 adressen terug
                sbc #32
                sta zp
                lda zp+1
                sbc #0
                sta zp+1
                dex                     ;doe dit voor iedere regel
                bne mem_page_down1
mem_page_up     jmp memedit0            ;dump volgende set regels
memedit_exit    jsr cursor_off
                rts

memedit2        jmp memedit4

mem_cur_up      lda mwrk+1              ;cursor op bovenste regel?
                cmp mwrk+5
memedit3        beq mem_test_key        ;ja, dan negeren
                dec mwrk+1              ;verlaag cursor y positie
mem_cur_xy      ldx mwrk                ;cursor naar nieuwe positie
                ldy mwrk+1
                jsr gotoxy
                jmp mem_test_key        ;ga volgende toetsdruk lezen

mem_cur_down    lda mwrk+1              ;cursor op onderste regel?
                clc
                adc #1
                cmp mwrk+6
                beq mem_test_key        ;ja, dan negeren
                inc mwrk+1              ;verhoog cursor y positie
                jmp mem_cur_xy

mem_cur_left    lda mwrk                ;cursor al uiterst links?
                cmp #4
                beq mem_test_key        ;ja, dan negeren
                sec
                sbc #3                  ;cursor drie posities naar links
                sta mwrk
                jmp mem_cur_xy          ;cursor naar nieuwe positie

mem_cur_right   lda mwrk                ;cursor al uiterst rechts?
                cmp #55
                beq memedit3            ;ja, dan negeren
                clc
                adc #3                  ;cursor drie posities naar rechts
                sta mwrk
                jmp mem_cur_xy

memedit4        ldx #7                  ;bewaar scherm
                ldy #6
                jsr scrcopy
                kader 34,20,47,17,1,$30 ;teken kader
                ldx #<memedit_text      ;druk tekst af
                ldy #>memedit_text
                jsr write
                jsr input               ;lees input
                ldx #6                  ;herstel scherm
                ldy #7
                jsr scrcopy
                lda #tekstkleur         ;herstel kleur
                jsr colour
                lda mwrk                ;adres of data aanpassen?
                cmp #10
                bcs mem_data_chg        ;spring indien data wijzigen
mem_adres_chg   lda iwrk                ;zet nieuw adres
                sta zp
                lda iwrk+1
                sta zp+1
                jmp memedit0

mem_data_chg    lda mwrk                ;bereken (mwrk-10)/3
                sec
                sbc #10
                ldx #0
mem_data_div3   cmp #0                  ;resultaat = 0
                beq mem_data_chg1
                inx                     ;x=x+1
                sec
                sbc #3                  ;bereken A/3 door herhaald aftrekken
                bne mem_data_div3       ;moet altijd deelbaar zijn door 3
mem_data_chg1   stx mwrk+3              ;berg op voor later gebruik
                stx zp+2                ;trek dat af van 16 (maar later is
                sec                     ;  een correctie nodig van -16,
                lda #00                 ;  vandaar laadt accu met 0)
                sta mwrk+7              ; later nodig
                sbc zp+2
                sta zp+2                ;bewaar resultaat even
                lda mwrk+6              ;bereken mwrk(6)-mwrk(1)
                sec
                sbc mwrk+1
                asl a                   ;vermenigvuldig met 16
                rol mwrk+7              ;  groot 16 bits getal
                asl a
                rol mwrk+7
                asl a
                rol mwrk+7
                asl a
                rol mwrk+7
                clc                     ;tel 0-(mwrk-10)/3 erbij op
                adc zp+2
                sta zp+2
                lda mwrk+7
                adc #0
                sta zp+3
                lda zp                  ;bereken uiteindelijk adres
                sec
                sbc zp+2
                sta zp+2                ;berg dit op in zeropage
                lda zp+1
                sbc mwrk+7
                sta zp+3
                ldx mwrk                ;zet cursor goed voor afdrukken data
                ldy mwrk+1
                jsr gotoxy
                lda zp+3                ;test of adres in verboden gebied ligt
                cmp #$B8
                bne mem_data_chg2
                lda zp+2
                bpl mem_data_chg2
                jmp mem_cur_xy          ;indien in i/o gebied dan exit edit
mem_data_chg2   lda iwrk                ;lees de input data
                ldy #0                  ;clear index
                sta (zp+2),y            ;schrijf data weg
                lda (zp+2),y            ;lees data (ivm read-only geheugen)
                pha                     ;bewaar data
                jsr prthex              ;druk hex waarde af op het scherm
                lda mwrk+3              ;laadt positie van "geheugenplaats"
                clc                     ;bereken positie in asciiblok
                adc #60
                tax                     ;zet in x register
                ldy mwrk+1              ;laadt regelnummer
                jsr gotoxy              ;zet cursor in asciiblok
                pla                     ;haal karakter terug van stack
                cmp #32                 ;waarde < 32
                bcs mem_data_chg3
                lda #'.'                ;ja, laadt '.'
mem_data_chg3   jsr wrch                ;druk karakter af
                jmp mem_cur_xy          ;cursor goed zetten en einde input

memedit_text    .db 31,35,18,"Enter value"
                .db 31,35,19,'?',0

test_io_range   clc                     ;clear carry voor berekening
                tya                     ;pointer naar a
                adc zp                  ;tel op
                pha                     ;bewaar resultaat
                lda zp+1
                adc #0
                cmp #$B8                ;valt binnen #B880...#B8FF
                bne not_io              ;nee, springen
                pla
                bpl not_io+1
                sec                     ;zet carry voor I/O
                rts
not_io          pla                     ;haal stack leeg
                clc                     ;wis carry voor geen I/O
                rts                     ;einde routine

memdump         lda #02                 ;zet bovenregel voor memory dump
                sta mwrk+5
                lda #23                 ;zet onderregel voor memory dump
                sta mwrk+6
                lda zp                  ;berg beginadres op in globale var
                sta mem_home
                lda zp+1
                sta mem_home+1
                ldx mwrk+5              ;laadt regelpointer
memedit1        stx mwrk+2              ;bewaar huidige regel
                ldx #3                  ;cursor naar volgende regel
                ldy mwrk+2
                jsr gotoxy
                ldy #0                  ;reset geheugenpointer
                ldx mwrk+2
                ldy #0                  ;reset pointer
mem_adres       lda #'#'                ;druk adres af
                jsr wrch
                lda zp+1
                jsr prthex
                lda zp
                jsr prthex
                lda #' '                ;gevolgd door twee spaties
                jsr wrch
                jsr wrch
mem_hexdump     jsr test_io_range       ;gebied #B880...#B8FF uitsluiten
                bcc mem_hexdump0        ;spring indien erbuiten
                lda #$B8                ;lees dummy waarde
                bne *+4                 ;gedwongen sprong
mem_hexdump0    lda (zp),y              ;lees geheugeninhoud
                jsr prthex              ;druk af
                lda #' '                ;print spatie
                jsr wrch
                iny                     ;verhoog pointer
                cpy #8                  ;halverwege?
                bne mem_hexdump1        ;nee, dan springen
                tya                     ;cursor stapje terug
                jsr wrch
                lda #250                ;druk puntje af
                jsr wrch
mem_hexdump1    cpy #16                 ;einde regel?
                bne mem_hexdump         ;nee, dan volgende byte
                lda #' '                ;gevolgd door twee spaties
                jsr wrch
                jsr wrch
                ldy #0                  ;reset pointer
mem_hexdump2    jsr test_io_range       ;gebied #B880...#B8FF uitsluiten
                bcc mem_hexdump2a       ;spring indien erbuiten
                lda #$B8                ;lees dummy waarde
                bne *+4                 ;gedwongen sprong
mem_hexdump2a   lda (zp),y              ;lees geheugeninhoud
                cmp #32                 ;waarde kleiner dan 32
                bcs mem_hexdump3        ;sping indien groter
                lda #'.'                ;voor ascii < ' ' puntje afdrukken
mem_hexdump3    jsr wrch                ;druk af
                iny                     ;verhoog pointer
mem_hexdump4    cpy #16                 ;einde regel?
                bne mem_hexdump2        ;nee, dan volgende byte
                clc                     ;verhoog geheugenpointer met 16
                lda zp
                adc #16
                sta zp
                lda zp+1
                adc #0
                sta zp+1
                inx                     ;verhoog huidig regelnummer
                cpx mwrk+6
                beq mem_dump_end
                jmp memedit1            ;spring indien niet einde scherm
mem_dump_end    rts                     ;einde routine

maintext1       .db 17,$4f,16,31,1,24
                .db "Atomic Memory Editor"
                .db 31,45,24
                .db "(c) 1996 Atomic Development Studio"
                .db 17,$1f,0
maintext2       .db 16,30
                .db "PgDn = Next ",179
                .db " PgUp = Previous ",179
                .db " Ins = Edit ",179
                .db " Esc = End ",179
                .db " Move cursor with arrows",26,0
