;***********************************************************************;
;*              M O S   E X T E N T I O N   R O M   1                  *;
;*---------------------------------------------------------------------*;
;*    doel           : MOS EXT ROM voor Atom-in-PC BBC Basic           *;
;*---------------------------------------------------------------------*;
;*    filenaam       : mosext.asm                                      *;
;*    auteur         : Roland Leurs                                    *;
;*                     The Atomic Development Studio                   *;
;*    ontwikkeld     : april 1998                                      *;
;*    laatste update :                                                 *;
;*---------------------------------------------------------------------*;
;*    assembleren    : x6502 mosext                                    *;
;*---------------------------------------------------------------------*;
;*    oproep         : automatisch na BREAK                            *;
;***********************************************************************;
                .list on
                org $A000-16

pcheader        .dw     pcheader+16, init
                .dw     0,0,0,0,0,0

; declaratie werkruimte in zeropage
		include definiti.inc                

;***********************************************************************
;* Initialisatie van MOS EXT ROM                                       *
;***********************************************************************

init            .db $BE                 ; herkenningsbyte $BE
                jmp mosextinit          ; entry: spring naar initialisatie
                jmp mosextmsg           ; entry: spring naar message
                .db $2A,<clitab,>clitab ; entry: command line interpreter
                .db $00,$00,$00         ; entry: osbyte uitbreiding
                .db $00,$00,$00         ; entry: osword uitbreiding

mosextinit      rts                     ; lang over nagedacht ;-)

mosextmsg       cmp #0			; alleen afdrukken als accu 0 is
		bne mosextmsg1		;  dus niet in resetroutine
		jsr print               ; druk volgende tekst af
                .db "MOS Extension Rom 1.00 - "
		.db "(c) 1998 Atomic Development Studio"
                .db 13,10,$EA
mosextmsg1      rts                     ; einde routine

version         .db "1.00",0            ; versie string


************************************************************************
;* Diverse hulproutines                                                *
;***********************************************************************

; zet semafoor voor pc communicatie
zetsem          lda #$1B                ; laadt osbyte code
                jsr osbyte
                bcc zetsem              ; blijf dit doen totdat toegang vrij
                rts                     ; einde routine

wissem          lda #$1A                ; reset semafoor
                jmp osbyte              ; einde routine

commando        pha                     ; save commando nummer
                lda #0                  ; stuur $00 byte
                jsr oszendbyte          ; naar pc
                pla                     ; haal commando nummer weer op
                jmp oszendbyte          ; stuur naar pc

; skip spaties in command line buffer
skipspace0      iny                     ; verhoog command line pointer
skipspace1      lda clbuffer,y          ; lees karakter
                cmp #' '                ; test op spatie
                beq skipspace0          ; volgende lezen bij spatie
                rts                     ; anders einde routine

savepar         sta par_a               ; zet parameters in call werkruimte
                stx par_x
                sty par_y
                rts

ascii2nibble    cmp #'0'                ; vergelijk met '0'
                bcc a2n_error           ; indien kleiner geen geldig digit
                cmp #'9'+1              ; vergelijk met '9+1'
                bcc a2n_l1              ; indien kleiner dan geldig digit
                and #$DF                ; maak hexadecimale digit
                sbc #$07
                bcc a2n_error           ; error als kleiner dan 'A'
                cmp #$40                ; test op 'F'
                bcs a2n_error           ; indien groter geen geldig digit
a2n_l1          sec                     ; zet carry voor aftrekken
                sbc #'0'                ; trek er ascii '0' af
                rts                     ; einde routine

ascii2digit     cmp #'0'                ; vergelijk met '0'
                bcc a2d_error           ; indien kleiner geen geldig digit
                cmp #'9'+1              ; vergelijk met '9+1'
                bcs a2d_error           ; indien groter geen geldig digit
a2d_l1          sec                     ; zet carry voor aftrekken
                sbc #'0'                ; trek er ascii '0' af
                rts                     ; einde routine

a2n_error       brk			; geneer foutmelding
                .db 28
                .db "Bad hex"
                .db 0

a2d_error       brk
                .db 16
                .db "Syntax error"
                .db 0

msdoscall       jsr zetsem		; zet semafoor
		lda #$22                ; commando: PC INT21h aanroep
                jsr commando
                ldx #0                  ; reset index
msdoscall1      lda zp,x                ; lees register waarde
                jsr zendbyte            ; stuur naar pc
                inx                     ; verhoog index
                cpx #8                  ; 8 bytes oversturen
                bne msdoscall1          ; spring voor volgend byte
                ldx #0                  ; reset index
msdoscall2      jsr leesbyte            ; lees resultaat registers
                sta zp,x                ; zet in zeropage
                inx                     ; verhoog index
                cpx #8                  ; 8 bytes lezen
                bne msdoscall2          ; spring voor volgend byte
		jsr wissem		; clear semafoor
                rts                     ; einde routine

getpar10	lda #0			; reset getal
		sta zp
getpar10l0      jsr skipspace1          ; lees digit
		cmp #$0D		; test op einde invoer
                beq getpar10l1          ; spring naar einde routine
		cmp #','		; test op comma
                beq getpar10l1          ; spring naar einde routine
		jsr ascii2digit		; maak er een decimale digit van
		jsr keer10		; vermenigvuldig met 10
		bvs a2d_error		; spring bij te groot getal
		clc			; wis carry voor optellen
		adc zp			; tel op bij getal
		sta zp			; slechts een byte groot
                iny                     ; verhoog pointer
                bne getpar10l0          ; volgende digit afhandelen
getpar10l1      lda zp                  ; laadt getal
		rts			; einde routine

keer10          pha                     ; save accu
                lda zp                  ; laadt vorige waarde
                asl a                   ; vermenigvuldig met 8
		asl a
		asl a
		clc			; wis carry voor optellen
                adc zp                  ; tel het getal erbij op
                adc zp                  ; en nogmaals erbij
                sta zp                  ; berg op
                pla                     ; herstel accu
                rts                     ; einde routine

wpoff		lda schaduwbyte		; lees latch status
		and #$DF		; clear bit 6
		sta schaduwbyte		; terugschrijven naar latch
		sta systemlatch
		rts

wpon		lda schaduwbyte		; lees latch status
		ora #$40		; set bit 6
		sta schaduwbyte		; terugschrijven naar latch
		sta systemlatch
		rts

************************************************************************
;* Commando's                                                          *
;***********************************************************************

clitab          .db "HELP"      , >help         , <help
		.db "FX"	, >fx		, <fx
;                .db "ENABLE"    , >enable       , <enable
;                .db "DISABLE"   , >disable      , <disable
		.dw $FFFF


; TIME, DATA, ROMS

help            lda #0
                jmp mosextmsg

fx		lda #0			; reset parameters
		sta par_a
		sta par_x
		sta par_y
		jsr skipspace1		; lees teken van commandline
		cmp #$0D		; lege string?
                beq fx3                 ; da's gelijk aan *FX 0
		jsr getpar10		; lees decimale parameter
		sta par_a
                jsr skipspace1          ; zoek comma
		cmp #$0D		; einde string?
		beq fx3			; ja, spring
		cmp #','		; comma?
		beq fx1			; ja, spring
		jmp a2d_error		; nee, dan foutmelding
fx1             iny
                jsr getpar10            ; lees decimale parameter
		sta par_x
                jsr skipspace1          ; zoek comma
		cmp #$0D		; einde string?
		beq fx3			; ja, spring
		cmp #','		; comma?
		beq fx2			; ja, spring
		jmp a2d_error		; nee, dan foutmelding
fx2             iny
                jsr getpar10            ; lees decimale parameter
		sta par_y
                jsr skipspace1          ; zoek einde regel
		cmp #$0D		; einde string?
		beq fx3			; ja, spring
		jmp a2d_error		; nee, dan foutmelding
fx3		lda par_a		; haal parameters op
		ldx par_x
		ldy par_y
		jmp osbyte		; voer osbyte routine uit
fx4             jmp a2d_error           ; spring naar error

disable		lda #$BD		; laadt disable code
		bne enable1		; spring altijd

enable		lda #$BE		; laadt enable code
enable1		sta zp			; berg op voor later
		jsr skipspace1		; lees parameter
		jsr ascii2digit		; maak-ter een digit van
		sta asave		; save romnummer
                jsr skipspace0          ; test op einde commandoregel
		cmp #$0D		 
                beq enable2             ; spring bij einde regel
		jmp a2d_error		; foute boel, geef melding
enable2		ldy asave		; laadt romnummer
		lda #<pagedrom		; zet romadres als parameter
                sta rdpgradr
		lda #>pagedrom
		sta rdpgradr+1
                jsr osrdpgrom           ; lees byte van paged rom
		cmp #$BE		; test op rom
		beq enable3		; spring indien rom aanwezig
		cmp #$BD
		beq enable3
noromfound	brk			; geen rom, geef foutmelding
		.db 222			; gelijk aan Channel error
		.db "No ROM available"
		.db 0
enable3		jsr wpoff		; write protect uitzetten
		lda asave		; laadt romnummer
		ora #$40		; set bit 6 voor schrijven naar rom
		tay			; zet in y register
		ldx zp			; laadt enable/disable code
                jsr osrdpgrom           ; zet in ROM
		jsr wpon		; zet write protect aan
		rts			; einde routine
