Jump to content

Recommended Posts

Ik ben aan het kijken of ik de P2000 cassette emulatie aan de praat kan krijgen in Mess. Het probleem is dat:

 

1. De documentatie niet lijkt te kloppen, of erg onduidelijk is. 

2. Ik geen fysieke P2000 heb.

 

Om alles aan de praat te krijgen moet ik begrijpen wat er allemaal gebeurt in port &H20 (0x20).  Volgens verschillende handleidingen ziet de poort er als volgt uit:

 

cas_inp: equ 20h ; input port for cassette

; bit 0 - Printer input

; bit 1 - Printer ready

; bit 2 - Strap N (daisy/matrix)

; bit 3 - Cassette write enabled (WEN)

; bit 4 - Cassette in position (CIP)

; bit 5 - Begin/end of tape (BET)

; bit 6 - Cassette read clock (RDC)

; bit 7 - Cassette read data (RDA)

 

Het gaat mij vooral om bit 3, 4, 5 en 6.

 

Zou iemand het volgende willen draaien op een echt P2000?

  1. Verwijder cassette:  PRINT INP(&H20)
  2. Plaats cassette:  PRINT INP(&H20)

Dit bevestigd of CIP bit hoog of laag is als de cassette aanwezig is.

 

Hetzelfde voor een cassette met en zonder "stopje"

  1. Cassette met het stopje verwijdert (schrijven naar cassette onmogelijk) PRINT INP(&h20)
  2. Cassette zonder stopje: PRINT INP(&h20)

Bevestigd of de WEN bit hoog of laag is als het stopje wel of niet aanwezig is.

 

Het RDC bit zou gebruikt moeten worden voor het kloksignaal. Het is mij niet duidelijk uit de handleiding hoe vaak de bit wisselt. Ik weet niet zeker of de resultaten hier zinvol zullen zijn:

 

10 PRINT peek(&H6010)INP(&H20):GOTO 10

 

Ik ben benieuwd of dit verschillende waardes oplevert voor de 2e kolom, of altijd dezelfde.

 

Om de 20ms zendt de P2000 een signaal naar port 10 (cassette, printer en toetsenbord). Veelal om het toetsenbord actief te maken.  Ik vraag me of of dit ook resulteert in het uitzetten van de cassette motor tijdens het terugspoelen. Een eenvoudige test is:

 

OUT &H10, &H4

 

Dit zet bit 3 en zet de terug spoel motor aan. Vraag is:

  1. Blijft de motor aan, of stopt hij meteen? 
  2. Stopt het terugspoelen aan het begin van de cassette of blijft het doorgaan? 

 

Als er geen rom in de P2000T steekt dan probeert de P2000t iets van cassette te laden (er verschijnt een T op het scherm). Kan iemand bevestigen of dit werkt?

 

 

 

 

 

Share this post


Link to post
Share on other sites

We zijn elkaar ook al tegengekomen op Circuits Online. Ik wil best wel jouw testjes doen 🙂

 

Ik kan ook alvast wat van mijn eigen bevindingen delen, want ik ben ook aan het uitzoeken hoe de P2000 een data blok van cassette leest.

Hoe het schrijven gaat staat voor daarna op de planning.

 

Allereerst: de Monitor ROM routines die met de cassette werken zetten de interrupt uit, om te voorkomen dat de interrupt de cassette control lijnen reset.

Wanneer je dus vanuit de prompt of in BASIC de cassette aanstuurt werkt dat ook alleen maar als je de interrupt uitzet...

 

Tijdens mijn analyses en testjes heb ik kunnen afleiden dat de clock, Bit 6 van inp(&H20), wisselt wanneer een (nieuw) data bit is gelezen en aanwezig is op Bit 7.

Op beide flanken, dus zowel hoog-laag als laag-hoog. Wanneer er geen data op de tape staat (lege tape of gedurende de gaps tussen Markers en Datablokken) wisselt de clock niet.

 

De cassetteroutine om een block te lezen werkt grofweg als volgt, voor zover ik heb kunnen uitvogelen: 

 

Aanname is dat de  cassette of is teruggespoeld, of is gestopt na het lezen of schrijven van een data block. Dan staat de leeskop op een GAP (lege tape) en zou een Marker moeten komen.

 

een Marker bestaat uit 4 bytes. 

- preamble (&HAA of binary 10101010)

- &H00

- &H00 

- postamble (&HAA)

 

De motor wordt gestart, en de code kijkt continu of het clock bit wisselt.

Bij de eerste wissel neemt de code aan dat dit bit 1 is van de preamble van de marker, en gaat na het verwerken van de preamble, door met bytes lezen, tellen en weggooien, tot er in een periode van ~5ms geen bit meer binnen komt.

Dan neemt de code aan dat Marker voorbij is en de volgende Gap bereikt.

 

Waren er meer of minder dan 3 bytes (nul, nul en postamble) geteld voordat de timeout kwam (kan komen doordat het een Datablock was, of lezen begon middenin een Mark of datablock) dan wordt een nieuwe poging gedaan de Marker te vinden. 

 

Wanneer succesvol een Marker is gelezen dan staat de leeskop (dus) op de Gap tussen Marker en Data, en volgt (als het goed is 🙂 ) een  datablock:

- preamble (&HAA of binary 10101010)

- Header (32 bytes)

- Payload (1024 bytes)

- postamble (&HAA)

 

Nu wordt weer op een eerste clock flip/data bit gewacht, en (als het goed is) het preamble byte ingelezen en weggegooid.

Meteen daarna worden de header, gevolgd door de data, ingelezen.

Daarna worden weer bytes  gelezen, geteld en weggegooid tot er een timeout is op het lezen van het volgende bit.

 

... Klaar! 

 

Niet helemaal: er volgt nog wat boekhouding om te bepalen of het een valide datablock was en berekend met hoeveel de klokteller moet worden opgehoogd om te corrigeren voor het feit dat de interrupt die niet kon ophogen.

Hoe dat allemaal gaat ben ik momenteel aan het uitzoeken, dus meer details heb ik nog niet.

 

Ferenc

 

toevoeging: 

 

dit zijn mijn aantekeningen bij in(0x20):

INPUT port 0x20-0x2f     cassette and printer
--------------------
bit    description
7    RDA     Data bit from cassette
6    RDC     ReaD Clock (goes High-Low or Low-High when a databit is ready)
5    BET     (N) Begin/End of tape signal 1= tape ok, 0 = begin/end
4    CIP     Cassette In Position = 1, no cassette = 0
3    WEN    (N) Write Enable 1=protected 0=can write
2    STRAP    (N) printer type (Daisy/Matrix) 
1    READY     printer ready connected to printer port pin 20
0    PRI       printer data in connected to printer port pin 2

 

 

Edited by HAL9000
spelvaudjes en port 20 databits

Share this post


Link to post
Share on other sites

Wedervraag:

welke bronnen gebruik jij?

 

en aan allen: Ik zoek documentatie/informatie over de floppy drives die je op de P2000T kon aansluiten...

 

Mijn P2000T heb ik op de kop getikt zonder drives/floppen 🙂

 

iemand?  

Edited by HAL9000

Share this post


Link to post
Share on other sites

Bedankt! Dat is erg bruikbaar.

 

Ik heb een assembly dump gemaakt van de rom en ben langzaam documentatie aan het toevoegen. Zie hier https://github.com/pokowaka/documentation/blob/master/programming/p2000.asm. Een vork van https://github.com/p2000t/documentation waar veel documentatie is te vinden. 

 

Hier is een stukje assembly wat suggereert dat WEN = 1 als write enabled is (stopje present)

 

castest:
      in       a,(cas_inp)    ;0b83    db  20 ; read port 20
      and      018h           ;0b85    e6  18 ; mask CIP WEN  (0001 1000)
      ret      z              ;0b87    c8     ; if (!CIP && !WEN) return 
      cp       018h           ;0b88    fe  18 ;  
      ret      z              ;0b8a    c8     ; if (CIP && WEN) return
      ld       a,"G"          ;0b8b    3e  47 ; Geen stopje error? (!WEN || !CIP), invariant?: WEN -> CIP
      ld       (caserror),a   ;0b8d    32  17  60 
      ret                     ;0b90    c9

 

Ik heb tot nu toe alleen het volgende aan mame toegevoegd:

 

- Fake cassette (memory blob)

- Fake rdc clock (volledig fout na het lezen van jou bericht).

- Ik doe nog niet het juiste met de lees vlaggen.

- Het "Maintenance" document https://github.com/pokowaka/documentation/blob/master/hardware/Maintenance.pdf benoemt een aantal test programma's. Het zou mooi zijn als iemand die nog zou hebben.

 

Mame is overigens niet erg stabiel 😞. Veelal bevriest de emulator. Mame klaagt over mijn SAA rom, dus misschien dat het daaraan ligt. 

 

Share this post


Link to post
Share on other sites

 

jouw testjes:

                                        dec  hex   binair
                                        --------------------
print inp(&h20) zonder cassette       : 187  0xBB  1011 1011
print inp(&h20) cassette zonder stopje: 171  0xAB  1010 1011
print inp(&h20) cassette met stopje   : 163  0xA3  1010 0011
                                                      ^ ^
                                                  CIP_| |_ WEN

CIP is blijkbaar ook 'inverted', en 0 als er een cassette is en 1 als er geen cassette is.

WEN = 0 als er geschreven kan worden en 1 als dat niet zo is (inverted)

Was dus fout in mijn analyse. Super, weer wat geleerd!

 

en 10 PRINT peek(&H6010)INP(&H20):GOTO 10 leverde een mooi oplopende eerste waarde en een constante waarde van 163 op voor de tweede

Dat is conform wat we verwachtten op basis van mijn eerdere beschrijving van hoe het clock-bit zich gedraagt.

 

tot slot, OUT &H10, &H4 spoelt de hele tape terug, en als de tape is teruggespoeld blijft de motor aan (geen EOT detectie actief die de motor uitzet)
Waarschijnlijk komt dit doordat de 0x04 op port 20 ook bit 6, KBIEN, uitzet en daarmee de interrupt. 

 

we worden nog weleens wijs!

 

laatste test:

bij geen cartridge en een tape in de recorder verschijnt er een knipperende 'T' op de bovenste regel.

De tape wordt teruggespoeld, en dan opgestart in een poging de eerste file te laden.

Ik had er een lege tape in gezet, dus er werd niks op tape gevonden

Vervolgens bleef de P2000T eindeloos proberen dat eerste block te vinden met die T bovenin beeld.

 

Edited by HAL9000
opstarten zonder cartridge, met tape toegevoegd

Share this post


Link to post
Share on other sites
41 minuten geleden, HAL9000 zei:

OUT &H10, &H4 spoelt de hele tape terug, en als de tape is teruggespoeld blijft de motor aan

Als je persé de MDCR naar de vaantjes wil helpen...

 

Alla, de andere drager waarover je 't had: heb je dan wel een floppy-controller in je P2000? Zoja, je zal allicht wat oudere types op de kop moeten kunnen tikken; ik heb een 5¼" Teac eraan hangen (ben 't typenummer even kwijt) en 2 Mitsubishi 3½" type MF353. Alle dubbelzijdig, max 80 tracks (*2) en max 6¼kB per track. De Upd765 kan meen ik max 5kB aan. Ofwel: 800kB max.

 

Helemaal zeker of een 1.44 niet lukt weet ik nog niet; ik heb ook nog een 3½" Canon liggen die ik eens eraan ga hangen.

 

Zie als je wil ook op COL.

 

En @pokowaka: hoezo heb je op github wel p2000t/documentation gevonden maar niet /software? Er staat 2* een Maintenance.bin...

Als je een EPROM-programmer hebt kun je vanalles uitproberen.

 

Share this post


Link to post
Share on other sites
44 minutes ago, cancom said:

Als je persé de MDCR naar de vaantjes wil helpen...

 

 

Ik zat als een havik op te letten en heb meteen het deurtje opengedaan, motor bleef draaien zonder dat de tape m tegenhield.

🙂

En Pokowaka heeft geen hardware, anders had ik die testjes niet hoeven doen denk ik...

 

Ik zal eens kijken of er een controller in een van mijn apparaten zit... is dat aan de buitenkant te zien?

 

Edited by HAL9000

Share this post


Link to post
Share on other sites
1 hour ago, cancom said:

heb je dan wel een floppy-controller in je P2000?

 

Nee, helaas... 

Ik heb wel een P2000M staan. Hopelijk is die interface vergelijkbaar met de insteekkaart voor de P2000T...

 

Edited by HAL9000

Share this post


Link to post
Share on other sites

@HAL9000 bedankt! Wij zijn in ieder geval een stap verder met de bits! @cancom bedankt voor het verwijzen naar de Maintenance module. Die had ik inderdaad gemist. De maintenance module zal het uitzoek werk waarschijnlijk een stuk makkelijker maken!

 

Ik heb al inderdaad al 30 jaar (of meer?) geen P2000 meer. Mijn kleinere ik had ooit een goed plan om het toetsenbord schoon te maken en toen waren er ineens geen toetsen meer 🙂

Share this post


Link to post
Share on other sites
10 uren geleden, HAL9000 zei:

tot slot, OUT &H10, &H4 spoelt de hele tape terug, en als de tape is teruggespoeld blijft de motor aan (geen EOT detectie actief die de motor uitzet)
Waarschijnlijk komt dit doordat de 0x04 op port 20 ook bit 6, KBIEN, uitzet en daarmee de interrupt.

 

Er hangt in een "kale" P2000 maar één ding aan de INT\ en dat is die key-interrupt-generator (gecontroleerd door KBIEN\ en LOCK\). BET dus niet!

Dat bit wordt enkel in de gaten gehouden door de cassroutines. Software, niks hardware.

 

8 uren geleden, HAL9000 zei:

Nee, helaas... 

Ik heb wel een P2000M staan. Hopelijk is die interface vergelijkbaar met de insteekkaart voor de P2000T...

 

Een complete M? 2 kasten? Dus met scherm/drives? Maar 2 gaten waar de 5¼ drives ooit gezeten hebben? Jammer dan.

 

Een floppykaart is niet een "insteek"-kaart maar ingebouwd boven het "moederbord".

 

Ik heb 't emailadres van @dionoid niet meer...

 

Share this post


Link to post
Share on other sites
13 hours ago, cancom said:

Er hangt in een "kale" P2000 maar één ding aan de INT\ en dat is die key-interrupt-generator (gecontroleerd door KBIEN\ en LOCK\). BET dus niet!

Dat bit wordt enkel in de gaten gehouden door de cassroutines. Software, niks hardware.

 

Geen hardware, klopt! Ik had eerder geschreven dat ik vermoedde dat de motor meteen uitgezet zou worden.

Ik had voor de waarde van de out &h44 gelezen en niet &h4, wat @pokowaka schreef.

Bij waarde &h44 wordt de motor wel meteen door de interrupt, als bijwerking van het (weer) aanzetten van KBIEN, uitgezet.

Dat heb ik net even getest.

13 hours ago, cancom said:

Een complete M? 2 kasten? Dus met scherm/drives? Maar 2 gaten waar de 5¼ drives ooit gezeten hebben? Jammer dan.

 

Een floppykaart is niet een "insteek"-kaart maar ingebouwd boven het "moederbord".

2000M: Ik heb een complete set, 2 kasten en in de monitorkast met daarin 2 drives, een stapel floppen en wat kopieën van handleidingen erbij, zie fotootje.

 

En je hebt gelijk, het is een inbouw- en niet een insteekkaart 🙂

2000M.jpg

Edited by HAL9000

Share this post


Link to post
Share on other sites

Wel hardware maar niet wat je denkt: out 16,68 houdt in dat je MDCR is voorzien van een terugspoelautomaatje. Dat is niet standaard!

 

En 't heeft niks te maken met de interrupt.

 

Share this post


Link to post
Share on other sites

Dankzij de gebruiksaanwijzing van de cassette recorder begint het de goede kant uit te gaan. De maintenance module slaagt nog niet maar schrijven en (offline) decoderen gaat al wel goed:

 

De file is gemaakt met Maintenance 2 module als volgt:

  • 9 - 1 >> Nu zit je in de debugger;
  • TB; Spoel tape terug
  • F 7100 400 CC; Fill memory region CC
  • F 7100 10 00 ; Fill memory region 16 bytes of 00 
  • F 7110 10 01; etc.. etc..
  • TW 7100 400; Schrijf memory region 1kb van vanaf address 7100
File: F7100-400-01-02.ok.txt1
aa 0 0 aa  [Sync marker]
aa  [Pre Amble]
0 71 0 4 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1  [Header]
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 a a a a a a a a a a a a a a a a b b b b b b b b b b b b b b b b c c c c c c c c c c c c c c c c d d d d d d d d d d d d d d d d e e e e e e e e e e e e e e e e f f f f f f f f f f f f f f f f cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  [Data]
a5 70  [Checksum]
aa  [Post Amble]

De data wordt in ieder geval goed weg geschreven. Probleem is nu uitzoeken hoe de klok precies werkt, want de write-skipback-read test slaagt nog niet.

 

Share this post


Link to post
Share on other sites

Ik ben weer een klein stukje verder. Blijkt dat er dus een flip-flop achter de RDC van de cassette recorder zit. (tsk, tsk, had ik gemist). Ik krijg nog een cassette fout B tijdens het lezen, maar blokken beginnen herkend to worden:

 

 

Screen Shot 2020-09-11 at 11.57.52 AM.png

Share this post


Link to post
Share on other sites

Nog een leuke ontdekking:

  1. De P2000 kan zowel vooruit, als achteruit van de MDCR lezen (en doet dit ook)
  2. Als de REV bit hoog is en de cassette terugspoelt dan worden RDC en RDA gewisseld. 

De reden waarom de Cassette fout B optreed is omdat de P2000 bits telt tijdens het terug spoelen en uiteindelijk het begin van de tape bereikt. Het goede nieuws is dat het nu lijkt of alles werkt!

Share this post


Link to post
Share on other sites
8 hours ago, pokowaka said:

 

De reden waarom de Cassette fout B optreed is omdat de P2000 bits telt tijdens het terug spoelen en uiteindelijk het begin van de tape bereikt. Het goede nieuws is dat het nu lijkt of alles werkt!

Mooi werk!!!

 

Kleine aanvulling: volgens mij (en mijn disassembly) telt de P2000 geen bits, maar seconden:

; cas_Rewind  (address 0x0bb4)
; rewinds tape for a maximum duration of 103 seconds.
; a verified data tape rewinds within 90-something seconds
; if EOT is not reached within 103 seconds, the tape is either broken
; or too long (not a supported tape) 
; inputs: none
; outputs: Cassette error contains no error, 'A' or 'I' 
cas_Rewind:
        call write_disabled             ; writing?
        ret nz                          ; yes! so don't rewind

        ld a,KBIEN|REV                  ; start rewinding
        out (CPOUT),a                   ; 
        ld b,103                        ; wait max 103 seconds  (1m 43s)
_rew_wait_loop:
        call wait_1second               ; this routine returns NZ when tape ejected or EOT is reached
        jr nz,_EOT_or_Ejected           ; EOT is what we want check this
        djnz _rew_wait_loop             ; keep rewinding for one more second 
        ld a,'I'                        ; still no eot after 103 seconds: Error 'I' means time out during rewind 
        ld (cassette_error),a           ; 
        ld c,00fh                       ; not sure why this is... ????

; status from wait_1_second can be:
; 0x41 = 'A' no tape
; 0x45 = 'E' end of tape (during write)
_EOT_or_Ejected:
        ld a,(cassette_error)           ; get error 
        cp 'E'                          ; equal to end of tape?
        jr nz,_was_ejected              ; no, other problem 
        ld a,0                          ; no error, because EOT is what we wanted here
        ld (cassette_error),a           ;
        ld hl,cassette_status           ;
        set 4,(hl)                      ; set begin of tape flag
        res 0,(hl)                      ; and start mark found (bit 0 == 0)
_was_ejected:
        ld h,'g'                        ; error code to write to comm port
        jp cas_motor_off                ; turn motor off and send h to comm (if this is enabled)

 

 

Edited by HAL9000
typo

Share this post


Link to post
Share on other sites

Dat is volgens mij de terugspoel routine. Ik ontdekte dat er in terug blok (0c61) routine iets vreemds aan de hand was. Hier zijn de stukjes:

 

;; Read the RDA state and set bit 5 in A
;; RDA_state | BET
;; Note when the tape is moving in reverse this actually gets the RDC bit.
get_rda:
      in       a,(cas_inp)    ;0cee    db  20
      and      080h           ;0cf0    e6  80
      set      5,a            ;0cf2    cb  ef
      ret                     ;0cf4    c9

      ;; This seems to read a byte when the tape is moving backwards.
      ;; Note that RDA <-> RDC when moving backwards.
      ;;
      ;; Args:
      ;;   A must contain the current state of RDC & BET
      ;;   D related to time we are willing to wait to see a byte.
      ;;
      ;; Returns:
      ;;   Sets the C flag in case of failure (beginning of tape, or tape removed.)
      ;;   Sets (caserror) with the actual error in case C is set
read_rev_byte:
      ld       c,008h         ;0cbf    0e  08        ; wait for at most 8 bits
rev_next_bit:
      xor      080h           ;0cc1    ee  80        ; Flip the expected RDA, we wait for next clock
      ld       h,a            ;0cc3    67           
l0cc4h:
      ld       b,000h         ;0cc4    06  00        ; Max time we are willing to wait for RDA clock signal, we loop 256 times
wait_for_rev_bit:
      ; Keep spinning until we have a bit flip
      in       a,(cas_inp)    ;0cc6    db  20        ;
      and      0b0h           ;0cc8    e6  b0        ; RDA, BET, CIP
      cp       h              ;0cca    bc            ; Is the clock state as expected?
      jr       z,rev_bit_available  ;0ccb    28  10  
      djnz     wait_for_rev_bit     ;0ccd    10  f7  ; Spin until RDA changes.
      and      030h           ;0ccf    e6  30        ; mask bet & cip
      cp       020h           ;0cd1    fe  20        ; this checks for errors.
      jr       nz,read_rev_err     ;0cd3    20  0d   ; Check if we are at the end, or cassette removed.
      dec      d              ;0cd5    15
      jr       nz,l0cc4h      ;0cd6    20  ec
      ld       a,h            ;0cd8    7c
      xor      080h           ;0cd9    ee  80
      inc      d              ;0cdb    14
      ret                     ;0cdc    c9
rev_bit_available:
      ;; This is called when we have a bit available..
      ld       a,h            ;0cdd    7c
      dec      c              ;0cde    0d
      jr       nz,rev_next_bit      ;0cdf    20  e0
      ret                     ;0ce1    c9  ; We have read 8 bits..

read_rev_err:
      ;; This happens when we hit the beginning of the tape, or if we
      ;; removed the tape while moving backwards.
      or       a              ;0ce2    b7
      ld       a,"E"          ;0ce3    3e  45   ; End of tape error
      jr       z,l0ce9h       ;0ce5    28  02
      ld       a,"A"          ;0ce7    3e  41   ; No tape
l0ce9h:
      ld       (caserror),a   ;0ce9    32  17  60
      scf                     ;0cec    37       ; Set the carry flag to indicate failure.
      ret                     ;0ced    c9

 

read_rev_byte lijkt alleen maar zinnig als het RDA bit wordt gebruikt als klok signaal. Wat blijkbaar ook het geval is.  Mame kan nu in ieder geval wav files schrijven en lezen, en een pull request is al open

https://github.com/mamedev/mame/pull/7215. Ik ben bezig met een converter van .cas -> wav zodat mame ook de cas files kan lezen.

 

Helaas bevatten de .cas files niet de checksum 😞

Share this post


Link to post
Share on other sites

Ik heb de checksum code achterhaald:

 

      and      001h           ;07ac    e6  01   ; DE with checksum is active
      xor      e              ;07ae    ab       ; a = written bit.
      ld       e,a            ;07af    5f       ; e = e ^ (bit written)
      and      001h           ;07b0    e6  01
      jr       z,l07d3h       ;07b2    28  1f   ; through a complex web it will jump to chksum (timing)
      ld       a,002h         ;07b4    3e  02
      xor      e              ;07b6    ab
      ld       e,a            ;07b7    5f       ; e = e ^ 0x02
      ld       a,040h         ;07b8    3e  40
chksum:
      xor      d              ;07ba    aa       ; a = d ^ (0x40 | 0x0)
      rra                     ;07bb    1f       ; >> 1
      rr       e              ;07bc    cb  1b   ; >> rotate through DE (i.e. e0 -> d7 etc..)
      jr       c,l07c2h       ;07be    38  02
      jr       l07c4h         ;07c0    18  02
l07c2h:
      or       080h           ;07c2    f6  80  ;
l07c4h:
      ld       d,a            ;07c4    57

In onleesbare c code:

 

void calc_chksum(uint16_t* de, bool bit)
{
	//  TODO Cleanup to something readable.
    uint8_t e = *de & 0xff;
    uint8_t d = (*de >> 8) & 0xff;
    e         = e ^ (bit ? 1 : 0);
    if (e & 0x01)
    {
        e = e ^ 2;
        d = d ^ 0x40;
    }
    else
    {
        d = d ^ 0x00;
    }
    bool c = d & 0x01;
    d >>= 1;
    bool cp = e & 0x01;
    e >>= 1;
    if (c)
    {
        e |= 0x80;
    }
    if (cp)
    {
        d |= 0x80;
    }
    *de = (d << 8) | e;
}

Mame kan nu native de .cas files inlezen. Met echte P2000t snelheid :-). 

Screen Shot 2020-09-14 at 12.35.35 AM.png

Share this post


Link to post
Share on other sites
4 hours ago, pokowaka said:

Ik heb de checksum code achterhaald:

 


      and      001h           ;07ac    e6  01   ; DE with checksum is active
      xor      e              ;07ae    ab       ; a = written bit.
      ld       e,a            ;07af    5f       ; e = e ^ (bit written)
      and      001h           ;07b0    e6  01
      jr       z,l07d3h       ;07b2    28  1f   ; through a complex web it will jump to chksum (timing)
      ld       a,002h         ;07b4    3e  02
      xor      e              ;07b6    ab
      ld       e,a            ;07b7    5f       ; e = e ^ 0x02
      ld       a,040h         ;07b8    3e  40
chksum:
      xor      d              ;07ba    aa       ; a = d ^ (0x40 | 0x0)
      rra                     ;07bb    1f       ; >> 1
      rr       e              ;07bc    cb  1b   ; >> rotate through DE (i.e. e0 -> d7 etc..)
      jr       c,l07c2h       ;07be    38  02
      jr       l07c4h         ;07c0    18  02
l07c2h:
      or       080h           ;07c2    f6  80  ;
l07c4h:
      ld       d,a            ;07c4    57

 

 

Deze code was ik ook al op gestuit, in de inlees routine, had ik even geparkeerd.  Mooi dat jij die uit elkaar hebt geplozen... 

Iets verderop wordt DE (checksum dus op dat moment!) weer gebruikt:

; data handling routine 'read payload'
; it stores the data byte at destination.
; HL, BC, DE contain dest, count and data
; not sure yet what DE means here ?? when all bytes were read (DE == 0) ???? 
; ?????
read_payload:
        exx				; save databyte, destination and count, get DE 
; next byte a filler or payload?
        ld a,d			; DE contains ????? 
        or e			;
        jr nz,set_carry		; DE not zero

        ex af,af'       ; get load control flags (P, C)
        xor a			; Set Z flag, set P, clear carry
        jp store_byte 
set_carry:
        ex af,af'		; get load control flags (P, C)
        scf				; Set Carry
        rla				; shift in A
        or a			; NZ, Set P 
store_byte:
        exx				; get data byte, dest and count
        ld (hl),d		; store data byte
        cpi	        	; inc HL, dec BC  P <- 0 when BC == 0
                        ; this triggers next len, dest and handler retrieval 
                        ; after finishing the data block
        exx				; save dest, count
        jr get_next_byte

 

 

Share this post


Link to post
Share on other sites
On 9/14/2020 at 9:36 AM, pokowaka said:

 


void calc_chksum(uint16_t* de, bool bit)
{
	//  TODO Cleanup to something readable.
    uint8_t e = *de & 0xff;
    uint8_t d = (*de >> 8) & 0xff;
    e         = e ^ (bit ? 1 : 0);
    if (e & 0x01)
    {
        e = e ^ 2;
        d = d ^ 0x40;
    }
    else
    {
        d = d ^ 0x00;
    }
    bool c = d & 0x01;
    d >>= 1;
    bool cp = e & 0x01;
    e >>= 1;
    if (c)
    {
        e |= 0x80;
    }
    if (cp)
    {
        d |= 0x80;
    }
    *de = (d << 8) | e;
}

Mame kan nu native de .cas files inlezen. Met echte P2000t snelheid :-). 

 

Leesbaarder:

 

            
de ^= bit;
if (de & 0x01) de ^= 0x4002;
// we rotate the bits, and lo bit of de wraps to hi bit
uint16_t hibit = (de & 0x01) ? 0x8000 : 0;
de = hibit|(de>>1);

 

Edited by HAL9000

Share this post


Link to post
Share on other sites

W00T! Cassette support is nu in Mame! Het is nog niet helemaal perfect:

 

- Soms onverwachte cassette fout L

- Soms lukt het niet om van een laad scherm (piraten avontuur, ghosthunt) de juiste file te laden.

 

Dit zijn waarschijnlijk timing gerelateerde problemen. 

 

- Ongerelateerd aan de mini cassette, soms hangt mame voor een paar seconden.

Share this post


Link to post
Share on other sites
On 9/15/2020 at 12:28 AM, HAL9000 said:

Leesbaarder:

 


            
de ^= bit;
if (de & 0x01) de ^= 0x4002;
// we rotate the bits, and lo bit of de wraps to hi bit
uint16_t hibit = (de & 0x01) ? 0x8000 : 0;
de = hibit|(de>>1);

 

Ja, dat is stukken beter!

Share this post


Link to post
Share on other sites
8 minutes ago, pokowaka said:

W00T! Cassette support is nu in Mame! Het is nog niet helemaal perfect:

 

- Soms onverwachte cassette fout L

- Soms lukt het niet om van een laad scherm (piraten avontuur, ghosthunt) de juiste file te laden.

 

Dit zijn waarschijnlijk timing gerelateerde problemen. 

 

- Ongerelateerd aan de mini cassette, soms hangt mame voor een paar seconden.

SUPER!

 

Share this post


Link to post
Share on other sites
On 9/13/2020 at 11:21 PM, pokowaka said:

Dat is volgens mij de terugspoel routine. Ik ontdekte dat er in terug blok (0c61) routine iets vreemds aan de hand was. Hier zijn de stukjes:

 


;; Read the RDA state and set bit 5 in A
;; RDA_state | BET
;; Note when the tape is moving in reverse this actually gets the RDC bit.
get_rda:
      in       a,(cas_inp)    ;0cee    db  20
      and      080h           ;0cf0    e6  80
      set      5,a            ;0cf2    cb  ef
      ret                     ;0cf4    c9

      ;; This seems to read a byte when the tape is moving backwards.
      ;; Note that RDA <-> RDC when moving backwards.
      ;;
      ;; Args:
      ;;   A must contain the current state of RDC & BET
      ;;   D related to time we are willing to wait to see a byte.
      ;;
      ;; Returns:
      ;;   Sets the C flag in case of failure (beginning of tape, or tape removed.)
      ;;   Sets (caserror) with the actual error in case C is set
read_rev_byte:
      ld       c,008h         ;0cbf    0e  08        ; wait for at most 8 bits
rev_next_bit:
      xor      080h           ;0cc1    ee  80        ; Flip the expected RDA, we wait for next clock
      ld       h,a            ;0cc3    67           
l0cc4h:
      ld       b,000h         ;0cc4    06  00        ; Max time we are willing to wait for RDA clock signal, we loop 256 times
wait_for_rev_bit:
      ; Keep spinning until we have a bit flip
      in       a,(cas_inp)    ;0cc6    db  20        ;
      and      0b0h           ;0cc8    e6  b0        ; RDA, BET, CIP
      cp       h              ;0cca    bc            ; Is the clock state as expected?
      jr       z,rev_bit_available  ;0ccb    28  10  
      djnz     wait_for_rev_bit     ;0ccd    10  f7  ; Spin until RDA changes.
      and      030h           ;0ccf    e6  30        ; mask bet & cip
      cp       020h           ;0cd1    fe  20        ; this checks for errors.
      jr       nz,read_rev_err     ;0cd3    20  0d   ; Check if we are at the end, or cassette removed.
      dec      d              ;0cd5    15
      jr       nz,l0cc4h      ;0cd6    20  ec
      ld       a,h            ;0cd8    7c
      xor      080h           ;0cd9    ee  80
      inc      d              ;0cdb    14
      ret                     ;0cdc    c9
rev_bit_available:
      ;; This is called when we have a bit available..
      ld       a,h            ;0cdd    7c
      dec      c              ;0cde    0d
      jr       nz,rev_next_bit      ;0cdf    20  e0
      ret                     ;0ce1    c9  ; We have read 8 bits..

read_rev_err:
      ;; This happens when we hit the beginning of the tape, or if we
      ;; removed the tape while moving backwards.
      or       a              ;0ce2    b7
      ld       a,"E"          ;0ce3    3e  45   ; End of tape error
      jr       z,l0ce9h       ;0ce5    28  02
      ld       a,"A"          ;0ce7    3e  41   ; No tape
l0ce9h:
      ld       (caserror),a   ;0ce9    32  17  60
      scf                     ;0cec    37       ; Set the carry flag to indicate failure.
      ret                     ;0ced    c9

 

read_rev_byte lijkt alleen maar zinnig als het RDA bit wordt gebruikt als klok signaal. Wat blijkbaar ook het geval is.  Mame kan nu in ieder geval wav files schrijven en lezen, en een pull request is al open

https://github.com/mamedev/mame/pull/7215. Ik ben bezig met een converter van .cas -> wav zodat mame ook de cas files kan lezen.

 

Helaas bevatten de .cas files niet de checksum 😞

Ik zie dat de 'read_rev_byte' routine ook wordt aangeroepen om bytes te skippen als de tape vooruit loopt (in de block_forward code), dus jouw hypothese dat RDC op RDA staat als REV actief is, lijkt niet te kloppen.
Volgens mijn analyse worden 8 data-bit transities geskipt in beide richtingen...

Dat zou een oorzaak kunnen zijn van het zo nu en dan niet goed kunnen 'doorladen', omdat de skip forward zich in jouw implementatie net iets anders gedraagt.

NB:

Ik heb inmiddels de hele monitor gedisassembleerd en ge reverse engineered, en zal de .asm files toevoegen aan de github repo,

Edited by HAL9000
typo

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×