;***********************************************************************
;*                 B B C   B A S I C   M O S R O M                     *
;*---------------------------------------------------------------------*
;*    doel           : Mosrom v4 voor BBC Basic Interpreter op         *
;*                     Atom-in-PC.                                     *
;*---------------------------------------------------------------------*
;*    filenaam       : bbcmos4.asm                                     *
;*    auteur         : Roland Leurs                                    *
;*                     The Atomic Development Studio                   *
;*    ontwikkeld     : maart 1998                                      *
;*    laatste update :                                                 *
;*---------------------------------------------------------------------*
;*    assembleren    : x6502 BBCMOS4                                   *
;*---------------------------------------------------------------------*
;*    oproep         : Laden als rom, initialiseren als extended reset *
;***********************************************************************

                org     $1000-16
                .list   on

_header         .dw     _header+16, init
                .dw     0,0,0,0,0,0

                include definiti.inc    ; definitie van werkruimte

;***********************************************************************
;* MOSROM Entry adressen                                               *
;***********************************************************************

irq_entry       jmp irqv                ; spring naar irq/brk routine
nmi_entry       jmp nmiv                ; spring naar nmi routine

;***********************************************************************
;* Diversen                                                            *
;***********************************************************************

; print string tot aan negatief byte
_print          pla                     ; haal adres van stack
                sta $E8                 ; zet in print pointer
                pla
                sta $E9
print1          ldy #$00                ; reset indexregister
                inc $E8                 ; verhoog pointer
                bne print2              ; spring bij pagina overschreiding
                inc $E9
print2          lda ($E8),y             ; lees karakter
                bmi print3              ; spring indien einde string
                jsr oswrch              ; druk karakter af
                jmp print1              ; ga volgend karakter lezen
print3          jmp ($E8)               ; einde routine

; print hex waarde van accu
_prthex         pha                     ; save byte
                lsr a                   ; schuif 4 maal
                lsr a
                lsr a                
                lsr a                
                jsr prtnibble           ; druk nibble af
                pla
prtnibble       and #$0F                ; maskeer hoge nibble
                cmp #10                 ; test op hex digit
                bcc prtnib1             ; spring indien geen hex digit
                adc #$06                ; optelling voor hex digit
prtnib1         adc #$30                ; maak ascii teken
                jmp oswrch              ; druk af en einde routine

; pc communicatie
zetsem          lda #$1B                ; laadt osbyte code
                jsr osbyte
                bcc zetsem              ; blijf dit doen totdat toegang vrij
                rts                     ; einde routine

wissem          lda #01                 ; reset semafoor
                sta semafoor
                rts                     ; einde routine

pccom           pha                     ; save commando nummer
                lda #0                  ; stuur $00 byte
                jsr oszendbyte          ; naar pc
                pla                     ; haal commando nummer weer op
                jmp oszendbyte          ; stuur naar pc

progescape      jsr escape              ; voer escape test uit
                jmp ($37)               ; vervolg bbc basic

listescape      jsr escape              ; voer escape test uit
                sta $14                 ; dit komt uit de basic interpreter
                ldx #$04
                jmp bbcbasic+$1929      ; ga verder met list statement

; test of escape toets gedrukt is
escape          php                     ; save alle processor registers
                pha
                txa
                pha
                tya
                pha
                lda esctoets            ; test of escape enabled is
                cmp #$FF
                beq escape1             ; spring indien escape disabled
                jsr scan81              ; kijk of een toets gedrukt is
                cpx esctoets            ; is escape toets gedrukt?
                bne escape1             ; spring indien geen toets gedrukt
                lda #-1                 ; zet escape vlag
                sta escvlag
escape1         pla                     ; herstel alle registers
                tay
                pla
                tax
                pla
                plp
                rts                     ; einde routine

; skip spaties in command line buffer
skipspace0      inx                     ; verhoog command line pointer
skipspace1      lda clbuffer,x          ; lees karakter
                cmp #' '                ; test op spatie
                beq skipspace0          ; volgende lezen bij spatie
                rts                     ; anders einde routine

; schakel paged rom in accu voor
schakel         pha                     ; save rom nummer
                lda schaduwbyte         ; lees huidig romnummer
                and #$F0                ; laagste nibble wissen
                sta schaduwbyte         ; schrijf ff weg
                pla                     ; herstel romnummer
                and #$0F                ; voorkom ellende
schakel1        ora schaduwbyte         ; bepaal nieuwe schakelstatus
                sta schaduwbyte         ; schrijf weg
                sta systemlatch         ; schakel rom voor
                rts                     ; einde routine

; lees pc timer
pctimer         jsr zetsem              ; zet semafoor
                ldx #0                  ; laadt teller
pctimer1        ldy #3                  ; laadt index
                lda #$5B                ; pc commando $5B03
                jsr pccom
                lda #$03
                jsr oszendbyte
pctimer2        lda pctimtab,x          ; lees getal uit timer tabel
                jsr oszendbyte          ; stuur naar pc
                inx
                dey                     ; verlaag index
                bpl pctimer2            ; spring indien er nog bytes volgen
                jsr osleesbyte          ; lees data byte van timer
                pha                     ; save op stack
                cpx #16                 ; vier adressen lezen
                bne pctimer1            ; volgende lezen
                ldx #3                  ; laadt teller
pctimer3        pla                     ; haal time van stack
                sta timer+5,x           ; zet in werkruimte
                dex                     ; verlaag teller
                bpl pctimer3
                inx                     ; x=0
                stx timer+9             ; zet in msb van time
                inx                     ; laadt teller met 1
pctimer4        asl timer+5             ; schuif rechts
                rol timer+6
                rol timer+7
                rol timer+8
                rol timer+9
                dex                     ; doe dat twee maal
                bpl pctimer4
                jmp wissem              ; einde routine

pctimtab        .db $6C,$00,$40,$00
                .db $6D,$00,$40,$00
                .db $6E,$00,$40,$00
                .db $6F,$00,$40
pctiminit       .db $00,$00,$00,$00,$00
                
;***********************************************************************
;* Initialisatie routine                                               *
;***********************************************************************

init            jsr wissem              ; reset semafoor voor pc communicatie
                ldx #$1F                ; laadt index
initvec         lda vectab,x            ; lees vector inhoud
                sta osvectors+4,x       ; zet in vector gebied
                dex                     ; verlaag index
                bpl initvec             ; spring indien nog vectoren volgen
                txs                     ; reset stack pointer
                lda #0
                sta escvlag             ; clear escape vlag
                sta spoolhandle         ; *SPOOL niet actief
                sta exechandle          ; *EXEC niet actief
                lda #27                 ; zet waarde van escape toets
                sta esctoets
                lda #$C7                ; writeprotect aan, OSRAM actief
                sta systemlatch         ; schrijf naar latch
                sta schaduwbyte         ; zet in schaduwbyte
                lda #$0A                ; karakter dat niet naar printer mag
                sta nietprinten
                lda #<bbcbasic+$E       ; zet adres van laatste "foutmelding"
                sta erroradres
                lda #>bbcbasic
                sta erroradres+1
                ldx #<pctiminit         ; reset timer
                ldy #>pctiminit
                lda #$02
                jsr osword              ; osword call $02
                lda bbcbasic+$15        ; laadt bbc basic release code
                cmp #'1'                ; test op release 1
                beq bbcmsg              ; spring indien geldige release code
                cmp #'2'                ; test op release 2
                beq bbcmsg              ; spring indien geldige release code
                jsr print               ; druk foutmelding af
                .db 12
                .db "BBC Basic interpreter not found",$0D,$0A
                .db "System halted ",$EA
                lda #$00                ; writeprotect uit
                sta systemlatch
                sta extresvec           ; disable bbc mode, na reset weer Atom
systemhalted    jmp systemhalted        ; geen basic, dan sterf maar af
bbcmsg          lda #$5B                ; zet terminal programma in BBC mode
                jsr pccom
                lda #$5A
                jsr oszendbyte
                lda #1
                jsr oszendbyte
                lda #22                 ; stel default scherm mode in
                jsr oswrch
                lda $1FFB               ; hier staat default scherm mode
                jsr oswrch
                lda #17                 ; stel default kleur in
                jsr oswrch
                lda $1FFC               ; hier staat default kleur
                jsr oswrch
                jsr print               ; druk welkomstekst af
                .db 6,12,15
                .db "BBC Basic Issue ",$EA
                lda bbcbasic+$15        ; laadt bbc basic release code
                jsr oswrch              ; druk release code af
                jsr print               ; vervolg met welkomstekst
                .db 13,10,10
                .db "MOS ROM V4.0"
                .db 13,10,10,$EA
                lda #maxromnr
pgrominit       jsr schakel             ; schakel paged rom voor
                lda pagedrom            ; test op aanwezigheid van mos ext rom
                cmp #$BE
                bne geenextrom          ; spring indien niet aanwezig
                jsr pagedrom+1          ; spring naar mos ext rom initroutine
                lda #1                  ; print optie
                jsr pagedrom+4          ; druk mos ext rom melding af
geenextrom      lda schaduwbyte         ; status van systeemlatch
                and #$0F                ; bepaal romnummer
                sec                     ; zet carry voor aftrekken
                sbc #1                  ; verlaag paged rom nummer
                bpl pgrominit           ; spring voor volgende paged rom
                jsr osnewl              ; cursor naar volgende regel
                ldx #0                  
                lda #$0F                ; flush alle buffers dmv osbyte &0F
                jsr osbyte
                lda #37                 ; default bell info
                sta bellf
                lda #6
                sta belld
                jsr bell                ; stel standaard bell in
                jsr print               ; druk 'basic' af
                .db "Basic",$0D,$0A,$0A,$EA
                lda #$01                ; laadt rom service code
                jmp bbcbasic            ; start basic


;***********************************************************************
;* PC Communicatie routines                                            *
;***********************************************************************

zendv           pha                     ; bewaar byte op stack
                sta systemvia           ; stuur byte naar pc
zendv1          lda systemvia+$D        ; lees statusregister
                and #$10                ; test of byte gelezen is
                beq zendv1              ; spring indien nog niet gelezen
                pla                     ; haal byte weer van stack
                rts                     ; einde routine

leesv           lda systemvia+$D        ; lees statusregister
                and #$02                ; test of byte klaar staat
                beq leesv               ; spring indien geen byte van pc
                lda systemvia+$1        ; lees byte
                rts


;***********************************************************************
;* Console routines                                                    *
;***********************************************************************

; oswrch: schrijf karakter naar beeldscherm
wrchv           sty ysavwrch            ; save y register
                ldy spoolhandle         ; test of *spool actief is
                beq wrchv0              ; spring indien niet actief
                jsr osbput              ; schrijf karakter naar file
wrchv0          ldy ysavwrch            ; herstel y register
                cmp #$00                ; test op $0
                bne wrchv1              ; spring indien geen $0
                jsr oszendbyte          ; voor $0 pccom#00 geven 
wrchv1          jmp oszendbyte          ; stuur byte naar pc

; osrdch: lees karakter van toetsenbord
rdchv           sty ysavrdch            ; save y register
                ldy exechandle          ; test of *exec actief is
                beq rdchv1              ; spring indien niet actief
                jsr osbget              ; lees karakter van file
                bcc rdchv0              ; spring indien geen eof
                lda #0                  ; sluit file af
                jsr osfind
                sta exechandle          ; clear handle voor *exec
                jmp rdchv1              ; lees teken alsnog van toetsenbord
rdchv0          ldy ysavrdch            ; herstel y register
                rts                     ; karakter uit file gelezen
rdchv1          ldy ysavrdch            ; herstel y register
rdchv2          jsr scan                ; scan toetsenbord
                cmp #$00                ; toets gedrukt ?
                beq rdchv2              ; nee, dan verder wachten
                rts                     ; einde routine

scan            php                     ; save processor status
                sei
                stx xsave               ; bewaar gebruikte registers
                sty ysave
                jsr zetsem              ; zet semafoor voor pc communicatie
                ldx #$00                ; default ascii waarde (geen toets)
                lda #$5D                ; geef scan commando aan pc
                jsr pccom
                jsr osleesbyte          ; lees toetsenbord status
                lsr a                   ; schuif toetsvlag in carry
                bcc endscan             ; einde routine als geen toets gedrukt
                jsr osleesbyte          ; lees ascii code van ingedrukte toets
                tax                     ; zet in x register
                jsr osleesbyte          ; lees scancode van ingedrukte toets
                tay                     ; zet in y register
                cpy #$0F                ; test op copy toets (=tab)
                bne scan_bs             ; spring als geen copy toets
                lda #$02                ; pccom $02: lees karakter op cursor
                jsr pccom
                jsr osleesbyte          ; lees resultaat
                tax                     ; zet in x register
                jmp endscan             ; einde routine
scan_bs         cpy #$0E                ; test op backspace toets
                bne scan_cur_u          ; spring indien geen backspace
                ldx #127                ; laadt delete code
                bne endscan             ; spring naar einde routine
scan_cur_u      cpx #$00                ; test op extended code
                bne endscan             ; spring als normale toets gedrukt is
                cpy #$48                ; cursor up?
                bne scan_cur_l          ; spring indien geen cursor up
                ldx #11                 ; laadt code voor cursor up
                bne endscan             ; spring naar einde routine
scan_cur_l      cpy #$4B                ; cursor left?
                bne scan_cur_r          ; spring indien geen cursor left
                ldx #8                  ; laadt code voor cursor left
                bne endscan             ; spring naar einde routine
scan_cur_r      cpy #$4D                ; cursor right?
                bne scan_cur_d          ; spring indien geen cursor right
                ldx #9                  ; laadt code voor cursor right
                bne endscan             ; spring naar einde routine
scan_cur_d      cpy #$50                ; cursor down?
                bne endscan             ; spring indien geen cursor down
                ldx #10                 ; laadt code voor cursor right
endscan         jsr wissem              ; reset semafoor voor pc communicatie
                txa                     ; zet ascii code in accu
                ldx xsave               ; herstel overige registers
                ldy ysave
                plp
                rts                     ; einde scan routine

scan81          jsr zetsem              ; zet semafoor voor pc communicatie
                ldx #$00                ; default ascii waarde (geen toets)
                lda #$5D                ; geef scan commando aan pc
                jsr pccom
                jsr osleesbyte          ; lees toetsenbord status
                lsr a                   ; schuif toetsvlag in carry
                bcc endscan81           ; einde routine als geen toets gedrukt
                jsr osleesbyte          ; lees ascii code van ingedrukte toets
                tax                     ; zet in x register
                jsr osleesbyte          ; lees scancode van ingedrukte toets
                tay                     ; zet in y register
endscan81       jmp wissem              ; clear semafoor en einde routine

wait81          jsr zetsem              ; zet semafoor
                lda #$19                ; wacht 1 timer tick
                jsr pccom
                lda #0                  ; geluid met frequentie 0
                jsr oszendbyte
                lda #1                  ; en duur 1
                jsr oszendbyte
                jmp wissem              ; einde routine

;***********************************************************************
;* Operating system calls                                              *
;***********************************************************************

bytev           sta asave               ; save registers
                stx xsave
                sty ysave
                cmp #$1B                ; osbyte &1B
                bne bytev1A
                lsr semafoor            ; schuif semafoorstatus in carry
                rts                     ; einde routine
bytev1A         cmp #$1A                ; osbyte &1A
                bne bytev7E
                jmp wissem              ; ga semafoor wissen
bytev7E         cmp #$7E                ; osbyte &7E
                bne bytev7F
                lda #$00                ; wis escape vlag
                sta escvlag
                rts                     ; einde routine
bytev7F         cmp #$7F                ; osbyte &7F
                bne bytev00
                lda #1                  ; laadt osfsc functienummer
                jmp osfsc
bytev00         cmp #$00                ; osbyte &00
                bne bytev0F
                cpx #0                  ; test call functie
                bne bytev00rts
                brk                     ; geef os versie
                .db 247                 ; error nummer
                .db "MOSROM v4 "
                .db "releasecode 98041702 {beta 1}",10,13
                .db "(c) 1998 Atomic Development Studio"
                .db 0
bytev00rts      ldx #4                  ; return versie nummer
                rts
bytev0F         cmp #$0F                ; test op osbyte &0F
                bne bytev15
                cpx #0                  ; test op keyboard buffer flush
                beq flush
                rts
bytev15         cmp #$15                ; test op osbyte &15
                bne bytevxx
flush           pha                     ; save accu
flush1          jsr scan                ; lees toets
                cmp #0
                bne flush1              ; totdat buffer leeg is
                pla                     ; herstel accu
                rts                     ; einde routine

bytevxx         and #$FF                ; bepaal sign van accu
                bpl byteerr             ; spring indien ongeldig
                asl a                   ; verdubbel accu
                tay                     ; zet in indexregister
                lda bytetab,y           ; laadt adres
                sta oswordspace         ; zet sprongadres
                lda bytetab+1,y
                sta oswordspace+1
                ldy ysave               ; herstel registers
                ldx xsave
                lda asave
                jmp (oswordspace)       ; voer routine uit
byteerr         lda #maxromnr           ; laadt hoogste rom nummer
byterom         jsr schakel             ; schakel rom voor
                lda pagedrom            ; test of rom aanwezig is
                cmp #$BE
                bne bytenext            ; nee, zoek volgende rom
                lda pagedrom+$A         ; test of rom osbyte routines heeft
                cmp #$2A
                bne bytenext            ; nee, zoek in volgende rom
                lda pagedrom+$B         ; laadt adres van call tabel
                sta oswordparm          ; zet in werkruimte
                lda pagedrom+$C
                sta oswordparm+1
                ldy #0                  ; reset pointer
                lda (oswordparm),y      ; lees aantal aanwezige call nrs
                tax                     ; zet als teller in x register
                iny
                lda (oswordparm),y      ; lees adres van sprongtabel
                sta oswordspace
                iny
                lda (oswordparm),y
                sta oswordspace+1
                lda asave               ; herstel osbyte call nummer
bytezoek        iny                     ; verhoog index
                lda (oswordparm),y      ; test of call aanwezig is
                cmp asave
                beq bytefound           ; spring indien gevonden
                dex                     ; verlaag teller
                bne bytezoek            ; spring indien nog niet klaar
bytenext        lda schaduwbyte         ; laadt huidig romnummer
                and #$0F                ; staat in laagste nibble
                sec                     ; trek-ter 1 van af
                sbc #1
                bpl byterom             ; ga verder met volgende rom
                jsr print               ; druk tekst af als nergens gevonden
                .db "OSBYTE &",$EA
                lda asave               ; haal osbyte nummer op
                jsr prthex              ; druk af
                jmp not_implemented     ; anders foutmelding geven
bytefound       dey                     ; verlaag index drie maal
                dey
                dey
                tya                     ; zet in accu
                asl a                   ; verdubbel index
                tay                     ; zet terug in index register
                lda (oswordspace),y     ; lees low byte sprong adres
                sta oswordparm
                iny                     ; verhoog index
                lda (oswordspace),y     ; lees high byte sprong adres
                sta oswordparm+1
                lda asave               ; herstel oorspronkelijke registers
                ldx xsave
                ldy ysave
                jsr doe_het             ; voer osbyte routine uit
                pha                     ; save accy
                lda #0                  ; herstel default rom nummer
                jsr schakel
                pla                     ; herstel accu
                rts                     ; einde osbyte routine
doe_het         jmp (oswordparm)        ; spring naar osbyte routine

bytev80         jsr zetsem              ; zet semafoor
                lda #$37                ; geef joystck commando
                jsr pccom
                jsr osleesbyte          ; lees status van joystick
                tax                     ; zet in y-register
                ldy #0                  ; high byte is 0
                jsr wissem              ; reset semafoor
                lda #$80                ; volgens voorschrift
                rts                     ; einde routine

bytev81         stx oswordspace+2       ; zet parameter in werkruimte
                sty oswordspace+3
                tya                     ; zet hoge byte van time in accu
                bmi bytev81n1           ; spring indien negatief
                lsr oswordspace+3       ; deel parameter door 4
                ror oswordspace+2
                lsr oswordspace+3
                ror oswordspace+2
bytev81l1       jsr scan81              ; voer keyboardscan uit
                cpx #0                  ; test of toets gedrukt is
                bne bytev81l3           ; spring indien toets gedrukt
                jsr wait81              ; wacht een timertick
                dec oswordspace+2       ; verlaag timer waarde
                lda oswordspace+2       ; test op overflow
                cmp #$FF
                bne bytev81l1
                dec oswordspace+3       ; verlaag hoge byte
                lda oswordspace+3
                cmp #$FF                ; test op einde der tijden
                bne bytev81l1
                ldy #$FF                ; laadt exit codes bij geen toets
bytev81l2       sec                     ; exit code indien bij toets
                rts                     ; einde routine
bytev81l3       cpx #27                 ; test op escape
                bne bytev81l4
                ldy #27                 ; laadt y register met escape code
                bne bytev81l2           ; gedwongen sprong
bytev81l4       ldy #$00                ; laadt exit codes bij toets
                clc
                rts                     ; einde routine

bytev81n1       txa                     ; zet neg. toetscode time in accu
                bpl bytev82             ; is toevallig hetzelfde
                pha                     ; save op stack
                jsr scan81              ; voer een keyboardscan uit
                pla                     ; herstel gevraagde toetscode
                cmp keybtab,y           ; zet om naar BBC keyboard code
                bne bytev82             ; spring indien niet gelijk
                ldx #$FF                ; laadt return code indien de
                ldy #$FF                ;    gevraagde toets ingedrukt is
                rts

bytev82         ldx #0                  ; laadt high order address
                ldy #0
                rts                     ; kort en krachtig

bytev83         ldx #<program           ; laadt OSHWM
                ldy #>program
                rts                     ; einde routine

bytev84         ldx #<pagedrom-1        ; laadt HIMEM
                ldy #>pagedrom-1
bytevDA         rts                     ; einde routine

bytev86         pha                     ; save accu
                jsr zetsem              ; zet semafoor voor pc communicatie
                lda #$1E                ; opvragen cursorpositie
                jsr pccom
                jsr osleesbyte          ; lees x positie
                tax                     ; zet in x register
                jsr osleesbyte          ; lees y positie
                tay                     ; zet in y register
                jsr wissem              ; reset semafoor
                pla                     ; herstel accu
                rts                     ; einde routine

bytev87         pha                     ; save accu
                jsr zetsem              ; zet semafoor voor pc communicatie
                lda #$02                ; opvragen cursorpositie
                jsr pccom
                jsr osleesbyte          ; lees x positie
                tax                     ; zet in x register
                jsr wissem              ; reset semafoor
                pla                     ; herstel accu
                rts                     ; einde routine

bytev8B         lda #0                  ; is gelijk aan osfsc 0
                jsr osfsc               ; handel het daar maar af
                lda #$8B                ; volgens voorschrift
                rts                     ; einde routine

bytevC6         ldx exechandle          ; laadt exec file handle
                rts

bytevC7         ldx spoolhandle         ; laadt spool file handle
                rts

bytevD5         lda bellf               ; laadt oude frequentie
                jsr value               ; bepaal nieuwe waarde
                sty bellf               ; zet nieuwe waarde
                jmp bell                ; stel nieuwe waarde in

bytevD6         lda belld               ; laadt oude duur
                jsr value               ; bepaal nieuwe waarde
                sty belld               ; zet nieuwe waarde
                jmp bell                ; stel nieuwe waarde in

bytevF2         lda schaduwbyte         ; laadt schaduwbyte
                jsr value               ; bepaal nieuwe waarde
                sty schaduwbyte         ; schrijf nieuwe waarde naar
                sty systemlatch         ;       schaduwbyte en systeemlatch
                rts                     ; einde routine

value           tax                     ; old value in x
                and ysave               ; new value = (old value) and y
                eor xsave               ; eor x
                tay                     ; new value in y
                rts

bell            jsr zetsem              ; zet semafoor
                lda #$1A                ; pc commando $1A
                jsr pccom
                lda bellf               ; stuur frequentie naar pc
                jsr oszendbyte
                lda belld               ; stuur duur naar pc
                jsr oszendbyte
                jmp wissem              ; einde routine via wissem

wordv           sta asave               ; save registers
                stx xsave
                sty ysave
                cmp #$0F                ; test op maximale osword nummer
                bpl worderr             ; spring indien ongeldig
                asl a                   ; verdubbel accu
                tay                     ; zet in indexregister
                lda wordtab,y           ; laadt adres
                sta oswordspace         ; zet sprongadres
                lda wordtab+1,y
                sta oswordspace+1
                ldy ysave               ; herstel registers
                ldx xsave
                lda asave
                jmp (oswordspace)       ; voer routine uit
worderr         lda #maxromnr           ; laadt hoogste rom nummer
wordrom         jsr schakel             ; schakel rom voor
                lda pagedrom            ; test of rom aanwezig is
                cmp #$BE
                bne wordnext            ; nee, zoek volgende rom
                lda pagedrom+$D         ; test of rom osword routines heeft
                cmp #$2A
                bne wordnext            ; nee, zoek in volgende rom
                lda pagedrom+$E         ; laadt adres van call tabel
                sta oswordparm          ; zet in werkruimte
                lda pagedrom+$F
                sta oswordparm+1
                ldy #0                  ; reset pointer
                lda (oswordparm),y      ; lees aantal aanwezige call nrs
                tax                     ; zet als teller in x register
                iny
                lda (oswordparm),y      ; lees adres van sprongtabel
                sta oswordspace
                iny
                lda (oswordparm),y
                sta oswordspace+1
                lda asave               ; herstel osword call nummer
wordzoek        iny                     ; verhoog index
                lda (oswordparm),y      ; test of call aanwezig is
                cmp asave
                beq wordfound           ; spring indien gevonden
                dex                     ; verlaag teller
                bne wordzoek            ; spring indien nog niet klaar
wordnext        lda schaduwbyte         ; laadt huidig romnummer
                and #$0F                ; staat in laagste nibble
                sec                     ; trek-ter 1 van af
                sbc #1
                bpl wordrom             ; ga verder met volgende rom
                jsr print               ; druk tekst af als nergens gevonden
                .db "OSWORD &",$EA
                lda asave               ; haal osword nummer op
                jsr prthex              ; druk af
                jmp not_implemented     ; anders foutmelding geven
wordfound       dey                     ; verlaag index drie maal
                dey
                dey
                tya                     ; zet in accu
                asl a                   ; verdubbel index
                tay                     ; zet terug in index register
                lda (oswordspace),y     ; lees low byte sprong adres
                sta oswordparm
                iny                     ; verhoog index
                lda (oswordspace),y     ; lees high byte sprong adres
                sta oswordparm+1
                lda asave               ; herstel oorspronkelijke registers
                ldx xsave
                ldy ysave
                jsr doe_het             ; voer osword routine uit
                pha                     ; save accy
                lda #0                  ; herstel default rom nummer
                jsr schakel
                pla                     ; herstel accu
                rts                     ; einde osword routine

; osword $00: Lees regel van standaard input device
wordv00         stx oswordparm          ; zet adres van inputbuffer
                sty oswordparm+1
                ldy #4                  ; laadt index
wordv00_0       lda (oswordparm),y      ; lees parameterblok
                sta oswordspace,y       ; zet in werkruimte
                dey                     ; verlaag index
                bpl wordv00_0           ; spring indien parameters volgen
                iny                     ; y=0
                bpl wordv00_4           ; spring altijd naar wordv00_3
wordv00_1       lda #$7                 ; genereer piepje
                dey                     ; verlaag y
wordv00_2       iny                     ; verhoog y
wordv00_3       jsr oswrch              ; spring naar schrijfroutine
wordv00_4       jsr osrdch              ; lees karakter van toetsenbord
                cmp #127                ; test op delete toets
                bne wordv00_5           ; spring indien geen delete
                cpy #0                  ; test op lege buffer
                beq wordv00_4           ; opnieuw bij delete op lege buffer
                dey                     ; anders pointer verlagen
                bcs wordv00_3           ; verwijder karakter van scherm
wordv00_5       cmp #21                 ; test op cancel (CTRL-U)
                bne wordv00_7           ; spring indien geen cancel
                tya                     ; zet pointer in accu
                beq wordv00_4           ; opnieuw bij cancel op lege buffer
                lda #$7F                ; laadt delete code
wordv00_6       jsr oswrch              ; verwijder karakter
                dey                     ; verlaag index
                bne wordv00_6           ; maak hele buffer leeg
                beq wordv00_4           ; begin opnieuw
wordv00_7       cmp esctoets            ; test op escape
                beq wordv00_10          ; sprint naar escaperoutine
                sta (oswordspace),y     ; zet karakter in buffer
                cmp #$0D                ; test op return
                beq wordv00_9           ; spring naar afronding
                cpy oswordspace+2       ; test op maximale input lengte
                bcs wordv00_1           ; spring als buffer vol
                cmp oswordspace+3       ; test op laagste geldige teken
                bcc wordv00_8           ; spring indien ok
                cmp oswordspace+4       ; test op hoogste geldige teken
                beq wordv00_2           ; spring indien gelijk
                bcc wordv00_2           ; spring indien kleiner
wordv00_8       cmp #32                 ; test op spatie
                bcc wordv00_3           ; spring en druk af indien groter
                bcs wordv00_4           ; ga volgende lezen indien kleiner
wordv00_9       jsr osnewl              ; cursor naar volgende regel
                ldx #0                  ; reset x register
                clc                     ; clear carry (geen escape)
                rts                     ; einde routine
wordv00_10      ldx #$FF                ; zet escape vlag
                stx escvlag
                rts                     ; einde routine

; osword $01: lees systeem timer
wordv01         stx oswordparm          ; zet adres van parameterblok
                sty oswordparm+1
                jsr pctimer             ; lees timer in timer[5]
                sec                     ; zet carry voor aftrekken
                ldy #0                  ; laadt index
                php
wordv01_0       plp
                lda timer+5,y           ; lees timer gegevens
                sbc timer,y             ; trek offset ervan af
                sta (oswordparm),y      ; zet in parameter
                iny                     ; verhoog index
                php
                cpy #5                  ; timer is vijf bytes groot
                bne wordv01_0           ; spring indien nog bytes volgen
                plp
                ldy #0                  ; laadt index
                clc                     ; zet carry voor optellen
wordv01_1       lda (oswordparm),y      ; lees timer offset
                adc timer+10,y          ; tel offset erbij
                sta (oswordparm),y      ; zet in parameter
                iny                     ; verhoog index
                cpy #5                  ; timer is vijf bytes groot
                bne wordv01_1           ; spring indien nog bytes volgen
                ldy oswordparm+1        ; herstel y register
                rts                     ; einde routine

; osword $02: zet systeem timer
wordv02         stx oswordparm          ; zet adres van parameterblok
                sty oswordparm+1
                jsr pctimer             ; lees timer in timer[5]
                ldy #0                  ; laadt index
wordv02_0       lda (oswordparm),y      ; lees parameter gegevens
                sta timer+10,y          ; zet in timer offset
                lda timer+5,y           ; laadt huidige pc timer
                sta timer,y             ; zet in timer geheugen
                iny                     ; verhoog index
                cpy #5                  ; timer is vijf bytes groot
                bne wordv02_0           ; spring indien nog bytes volgen
                ldy oswordparm+1        ; herstel y register
                rts                     ; einde routine

; osword $05: lees pc geheugen
wordv05         stx oswordspace         ; zet adres van parameterblok
                sty oswordspace+1
                jsr zetsem              ; wacht op pc toegang
                lda #$5B                ; commando $5B
                jsr pccom
                lda #$03                ; subfunctie 3
                jsr oszendbyte
                ldy #0                  ; reset index register
wordv05_0       lda (oswordspace),y     ; laadt offset / segment adres
                jsr oszendbyte          ; stuur naar pc
                iny                     ; verhoog index
                cpy #4                  ; vier bytes verzonden
                bne wordv05_0           ; nee, dan volgende byte sturen
                jsr osleesbyte          ; lees data van pc
                sta (oswordspace),y     ; zet data in parameterblok
                jmp wissem              ; reset semafoor en einde routine

; osword $06: schrijf pc geheugen
wordv06         stx oswordspace         ; zet adres van parameterblok
                sty oswordspace+1
                jsr zetsem              ; wacht op pc toegang
                lda #$5B                ; commando $5B
                jsr pccom
                lda #$04                ; subfunctie 4
                jsr oszendbyte
                ldy #0                  ; reset index register
wordv06_0       lda (oswordspace),y     ; laadt offset / segment adres / data
                jsr oszendbyte          ; stuur naar pc
                iny                     ; verhoog index
                cpy #5                  ; vier bytes verzonden
                bne wordv06_0           ; nee, dan volgende byte sturen
                jmp wissem              ; reset semafoor en einde routine

wordv07         stx oswordparm          ; zet adres van parameterblok
                sty oswordparm+1
                jsr zetsem              ; zet semafoor
                lda #$19                ; geef pc commando
                jsr pccom
                ldy #4                  ; index voor toonhoogte
                lda (oswordparm),y      ; lees toonhoogte
                jsr oszendbyte          ; stuur naar pc
                ldy #6                  ; index voor toonduur
                lda (oswordparm),y      ; lees toonduur
                jsr oszendbyte          ; stuur naar pc
                jmp wissem              ; reset semafoor en einde routine


nmiv            pha                     ; save accu
                jmp (osvectors)         ; spring naar de NMI routine

irqv            sta irqaccu             ; save accu
                pla                     ; haal processor status van stack
                pha                     ; en zet weer terug
                and #$10                ; test interrupt of brk instructie
                bne brkv                ; spring bij een brk instructie
                lda irqaccu             ; herstel accu
                pha                     ; zet op stack (conform Atom !!!)
                jmp (osvectors+4)       ; spring naar irq1v bij interrupt

brkv            plp                     ; haal status van stack
                cli                     ; enable interrupts
                cld                     ; clear decimal flag
                pla                     ; haal lsb adres van stack
                sec                     ; zet carry voor aftrekken
                sbc #1                  ; trek er 1 af
                sta erroradres          ; zet low byte van error adres
                pla                     ; haal msb adres van stack
                sbc #0
                sta erroradres+1        ; zet high byte van error adres
                jmp (osvectors+2)       ; spring naar breakhandler

cliv            sta asave               ; save accu, x en y registers
                stx xsave
                sty ysave
                ldy #0                  ; reset command line pointer
                ldx #$FF                ; reset index
                lda (xsave),y           ; lees command line
                cmp #'*'                ; skip asterisk
                bne cliv_1              ; spring indien geen asterisk
cliv_0          iny                     ; verhoog command line pointer
cliv_1          inx                     ; verhoog index
                lda (xsave),y           ; lees command line
                sta clbuffer,x          ; zet in command line buffer
                cmp #$0D                ; test op einde regel
                bne cliv_0              ; spring als nog karakters volgen
                lda #0                  ; laadt laagste romnummer
cliv_p1         jsr schakel             ; schakel paged rom voor
                lda pagedrom            ; test of rom aanwezig is
                cmp #$BE
                bne cliv_next           ; spring als geen rom aanwezig is
                lda pagedrom+7          ; test of cli tabel aanwezig is
                cmp #$2A
                bne cliv_next
                lda pagedrom+8          ; laadt tabel adres
                sta oswordparm
                lda pagedrom+9
                sta oswordparm+1
                ldy #$FF                ; reset tabel index
                cld                     ; zeker niet decimaal werken
cliv_4          ldx #$00                ; reset command line pointer
                jsr skipspace1          ; ga spaties overslaan
                dex                     ; zet command line pointer 1 terug
cliv_2          inx                     ; verhoog command line pointer
                iny                     ; verhoog tabel index
cliv_5          lda (oswordparm),y      ; lees karakter uit tabel
                bmi cliv_6              ; spring bij einde statement
                cmp clbuffer,x          ; vergelijk met buffer
                beq cliv_2              ; spring indien gelijk
                dey                     ; verlaag tabel index
cliv_3          iny                     ; verhoog tabel index
                lda (oswordparm),y      ; lees volgend teken uit tabel
                bpl cliv_3              ; volgende lezen als niet einde stat.
                iny                     ; verhoog tabel index
                lda clbuffer,x          ; lees teken uit buffer
                cmp #'.'                ; test op afkorting
                bne cliv_4              ; geen afk., zoek volgend statement
                inx                     ; wel afk., verhoog buffer pointer
                dey                     ; verlaag tabel pointer
                bcs cliv_5              ; zoek verder
cliv_6          sta oswordspace+4       ; zet msb van adres in zeropage
                iny
                lda (oswordparm),y      ; lees lsb van adres uit tabel
                sta oswordspace+3       ; zet in zeropage
                and oswordspace+4       ; test op geldig adres
                cmp #$FF
                beq cliv_next           ; spring als commando niet in tabel
                clc                     ; wis carry
                txa                     ; pointer naar commandline
                tay                     ; naar y register kopieren
                jsr cliv_run            ; voer *-commando uit
                lda #0                  ; schakel default rom voor
                jsr schakel
                ldy ysave               ; herstel accu, x en y registers
                ldx xsave
                lda asave
                rts                     ; einde cli routine
cliv_next       lda schaduwbyte         ; lees huidige latch status
                and #$0F                ; bepaal romnummer
                clc                     ; wis carry voor optellen
                adc #1                  ; verloog romnummer
                cmp #maxromnr+1         ; test op laatste rom
                bne cliv_p1             ; spring voor zoeken in volgende rom
                lda #0                  ; schakel terug naar paged rom 0
                jsr schakel
                lda #3                  ; onbekend commando, laadt fsc functie
                ldx #<clbuffer          ; laadt adres van command line string
                ldy #>clbuffer
                jmp osfsc               ; handel dit af via osfsc routines

cliv_run        jmp (oswordspace+3)     ; voer statement uit, y=bufferpointer

cli_error       brk                     ; genereer foutmelding
                .db $FE                 ; error code
                .db "Bad command"       ; error tekst
                .dw 0                   ; einde string

osrdpgromv      lda schaduwbyte         ; lees schaduwbyte
		pha			; bewaar in zeropage
		tya			; zet romnummer in accu
		bmi rdpgrom1		; spring indien subroutine uitvoeren
		and #$40		; test op schrijven
                beq rdpgrom0            ; spring om te lezen
                tya                     ; romnummer opnieuw naar accu
		and #$0F		; maskeer romnummer
                jsr schakel             ; schakel rom voor
		sty ysave		; bewaar romnummer
		ldy #0			; reset indexregister
		txa			; byte naar accu
		sta (rdpgradr),y	; schrijf byte
		ldy ysave		; herstel romnummer
		jmp rdpgrom2		; einde routine
rdpgrom0        tya                     ; romnummer opnieuw naar accu
                and #$0F                ; maskeer romnummer
                jsr schakel             ; schakel rom voor
		sty ysave		; bewaar romnummer
		ldy #0			; reset indexregister
		lda (rdpgradr),y	; lees byte
		ldy ysave		; herstel romnummer
		jmp rdpgrom2		; einde routine
rdpgrom1        tya                     ; romnummer opnieuw naar accu
                and #$0F                ; maskeer romnummer
                jsr schakel             ; schakel rom voor
		jsr rdpgrom3		; voer routine uit
rdpgrom2	sta asave		; save accu
		pla			; laadt aanroepende rom nummer
                jsr schakel             ; schakel terug naar aanroepende rom
		lda asave		; herstel accu		
		rts
rdpgrom3        jmp (rdpgradr)          ; spring naar routine

irq1v
irq2v           rti
filev           nop
argsv           nop
bgetv           nop
bputv           nop
gbpbv           nop
findv           nop
fscv            nop

not_implemented brk                     ; Not implemented
                .db 255                 ; error 255
                .db "OS call not implemented"
                .db 0

;***********************************************************************
;* Tabellen                                                            *
;***********************************************************************

keybtab         .db $00,$8F,$CF,$CE,$EE,$ED,$EC,$CB    ; 00..07
                .db $DB,$EA,$D9,$D8,$E8,$D7,$A6,$9F    ; 08..0F
                .db $EF,$DE,$DD,$CC,$DC,$BB,$CA,$DA    ; 10..17
                .db $C9,$C8,$C7,$A7,$B6,$00,$BE,$AE    ; 18..1F
                .db $CD,$BC,$AC,$AB,$BA,$B9,$A9,$A8    ; 20..27
                .db $B7,$B8,$00,$87,$9E,$BD,$AD,$9C    ; 28..2F
                .db $9B,$AA,$9A,$99,$98,$97,$00,$D7    ; 30..37
                .db $00,$9D,$00,$8E,$8D,$8F,$EB,$8B    ; 38..3F
                .db $8C,$E9,$89,$88,$DF,$00,$00,$81    ; 40..47
                .db $C6,$82,$F1,$E6,$84,$86,$F0,$85    ; 48..4F
                .db $D6,$83,$96,$FD                    ; 50..53

wordtab         .dw wordv00, wordv01, wordv02, worderr, worderr
                .dw wordv05, wordv06, wordv07, worderr, worderr
                .dw worderr, worderr, worderr, worderr, worderr
                .dw worderr

bytetab         .dw bytev80,bytev81,bytev82,bytev83,bytev84,bytev84,bytev86 ;80
                .dw bytev87,byteerr,byteerr,byteerr,bytev8B,byteerr,byteerr ;87
                .dw byteerr,byteerr,byteerr,byteerr,byteerr,byteerr,byteerr ;8E
                .dw byteerr,byteerr,byteerr,byteerr,byteerr,byteerr,byteerr ;95
                .dw byteerr,byteerr,byteerr,byteerr,byteerr,byteerr,byteerr ;9C
                .dw byteerr,byteerr,byteerr,byteerr,byteerr,byteerr,byteerr ;A3
                .dw byteerr,byteerr,byteerr,byteerr,byteerr,byteerr,byteerr ;AA
                .dw byteerr,byteerr,byteerr,byteerr,byteerr,byteerr,byteerr ;B1
                .dw byteerr,byteerr,byteerr,byteerr,byteerr,byteerr,byteerr ;B8
                .dw byteerr,byteerr,byteerr,byteerr,byteerr,byteerr,byteerr ;B8
                .dw bytevC6,bytevC7,byteerr,byteerr,byteerr,byteerr,byteerr ;C6
                .dw byteerr,byteerr,byteerr,byteerr,byteerr,byteerr,bytevDA ;CD
                .dw bytevDA,bytevD5,bytevD6,byteerr,byteerr,byteerr,bytevDA ;D4
                .dw byteerr,byteerr,byteerr,byteerr,byteerr,byteerr,byteerr ;DB
                .dw byteerr,byteerr,byteerr,byteerr,byteerr,byteerr,byteerr ;E2
                .dw byteerr,byteerr,byteerr,byteerr,byteerr,byteerr,byteerr ;E9
                .dw byteerr,byteerr,bytevF2,byteerr,byteerr,byteerr,byteerr ;F0
                .dw byteerr,byteerr,byteerr,byteerr,byteerr,byteerr,byteerr ;F7
                .dw byteerr,byteerr                                         ;FE

;***********************************************************************
;* Systeemvectoren                                                     *
;***********************************************************************

                org $1FA2

vectab          .dw irq1v,irq2v,cliv,bytev,wordv,wrchv
                .dw rdchv, filev,argsv,bgetv,bputv,gbpbv,findv,fscv
                .dw leesv, zendv

_osrdpgrom      jmp osrdpgromv
_oszendbyte     jmp (osvectors+$22)
_osleesbyte     jmp (osvectors+$20)
_osfsc          jmp (osvectors+$1E)
_osfind         jmp (osvectors+$1C)
_osgbpb         jmp (osvectors+$1A)
_osbput         jmp (osvectors+$18)
_osbget         jmp (osvectors+$16)
_osargs         jmp (osvectors+$14)
_osfile         jmp (osvectors+$12)
_osrdch         jmp (osvectors+$10)
_osasci         cmp #$0D
                bne _oswrch
_osnewl         lda #$0A
                jsr _oswrch
                lda #$0D
_oswrch         jmp (osvectors+$0E)
_osword         jmp (osvectors+$0C)
_osbyte         jmp (osvectors+$0A)
_oscli          jmp (osvectors+$08)

defaultvrij     .db 0                   ; tja...wat doen we hier nog mee?
defaultmode     .db 6                   ; 40 kolommen
defaultkleur    .db 3                   ; lichtblauw
extresvec       .db $F0,<init,>init
