disasm_with_labels.asm 234 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854
  1. ; z80dasm 1.1.3
  2. ; command line: z80dasm -l -s rom_strings.sym -g 0x0000 -a metric_cpu-s_mc8_v1.2_2716.bin
  3. ;##############################################################################
  4. ; METRIC 8 COMPUTER SYSTEM
  5. ; MONITOR/DEBUGGER REFERENCE MANUAL
  6. ;##############################################################################
  7. ;
  8. ; SYSTEM OVERVIEW:
  9. ; The Metric 8 is a sophisticated Z80-based computer system (circa 1980) with
  10. ; an advanced monitor/debugger ROM providing comprehensive development tools.
  11. ;
  12. ; HARDWARE SPECIFICATIONS:
  13. ; • CPU: Z80 running at 3.93216MHz (sophisticated timing), crystal at 19.6608MHz
  14. ; • ROM: 2 pcs of 2716 EPROM (2KB) containing monitor/debugger
  15. ; • RAM: 1KB base workspace + 64KB paged external memory
  16. ; • I/O: Z80 DMA controller, NEC µPD765A FDC, sophisticated peripherals
  17. ; • Memory Management: Advanced paging system with 8KB windows
  18. ;
  19. ; MONITOR COMMANDS:
  20. ; The monitor provides a '>' prompt and accepts single-letter commands
  21. ; followed by hexadecimal parameters. All addresses are 4-digit hex.
  22. ;
  23. ; MEMORY MODIFICATION COMMANDS:
  24. ;
  25. ; DEBUGGING/BREAKPOINT COMMANDS:
  26. ; • B XXXX - Set execution counter for controlled stepping (Entry: 0x03E2h)
  27. ; Sets execution step counter for controlled program stepping/tracing
  28. ; XXXX = number of instructions to execute before breaking
  29. ; Counter stored at memory location 0x011D0
  30. ; Default count is 1 if no parameter provided (single step)
  31. ; Used for single-step debugging and controlled execution
  32. ;
  33. ; MEMORY COMMANDS:
  34. ; • C AAAA BBBB CCCC - Compare memory regions (Entry: 0x0323h)
  35. ; Compare memory from AAAA-BBBB with memory starting at CCCC
  36. ; Displays differences between the two memory regions
  37. ; Silent operation if regions are identical
  38. ;
  39. ; • D [AAAA] [BBBB] - Display/Examine memory (Entry: 0x0358h)
  40. ; D AAAA BBBB: Memory dump display from address AAAA with length BBBB
  41. ; D AAAA: Interactive examine/modify starting at address AAAA
  42. ; D: Interactive examine/modify from current address
  43. ; Interactive mode: Shows one byte, Enter=next, Q=quit, hex=change value
  44. ;
  45. ; • E [XX] - Examine/modify CPU registers (Entry: 0x0515h)
  46. ; E: Display all Z80 registers in formatted list with current values
  47. ; Shows: A,B,C,D,E,F,H,L,I,A',B',C',D',E',F',H',L',IX,IY,PC,SP
  48. ; E XX: Examine/modify specific register (e.g., "E AF", "E BC", "E HL")
  49. ; Output format: "B 0A" (register name, space, 2-digit hex value)
  50. ; • F AAAA BBBB DD - Fill memory range with data (Entry: 0x03B7h)
  51. ; Fill memory from AAAA to BBBB with byte value DD
  52. ; Useful for initializing memory regions
  53. ; Fast memory pattern fill operation
  54. ;
  55. ; • M AAAA BBBB CCCC - Memory move/copy command (Entry: 0x04FCh)
  56. ; Copy memory block from AAAA-BBBB to destination starting at CCCC
  57. ; Uses LDIR instruction for efficient block transfer
  58. ; Handles overlapping regions properly
  59. ;
  60. ; EXECUTION COMMANDS:
  61. ; • G XXXX - Go/Execute program starting from address XXXX (Entry: 0x044Ah)
  62. ; Transfers control to user program at specified address
  63. ; Restores all CPU registers and begins execution
  64. ; Supports breakpoint detection and interrupt handling
  65. ; Returns to monitor if breakpoint hit or program exits
  66. ;
  67. ; • I XXXX - Configure debug display parameters and modes (Entry: 0x03CFh)
  68. ; Sets debugging display parameters stored at 0x11D6
  69. ; Used for display width, format, or visualization options
  70. ; Special case: "II" jumps to specialized display handler
  71. ;
  72. ; • J XXXX - Jump/Execute program (alternate Go command) (Entry: 0x0441h)
  73. ; Similar functionality to G command - executes program
  74. ; Parses hex address and transfers control to user program
  75. ; Supports same breakpoint and register restoration features
  76. ;
  77. ; FILE/DATA TRANSFER COMMANDS:
  78. ; • L XXXX - Load Intel HEX records into memory (Entry: 0x089Fh)
  79. ; Advanced Intel HEX format loader for program/data transfer
  80. ; XXXX parameter specifies base load address (optional, defaults to 0x0000)
  81. ; Parses Intel HEX records: ":LLAAAATTDDDDDDCC" format
  82. ; LL=byte count, AAAA=address, TT=record type, DD=data, CC=checksum
  83. ; Validates checksums and loads data to calculated addresses
  84. ; Essential for loading programs from external sources or storage
  85. ; Searches for ':' record start markers and processes complete records
  86. ;
  87. ; SYSTEM DISPLAY COMMANDS:
  88. ; • R AAAA BBBB - Read from disk/storage device (Entry: 0x09FFh)
  89. ; Read data from disk into memory starting at AAAA with length BBBB
  90. ; Uses disk parameters previously configured by O command
  91. ; Example: After "O 0 0 5 1", then "R 1000 100" reads 1 sector into 1000h
  92. ; Uses floppy disk controller (ports 0xF0, 0xF1, 0xFC)
  93. ; Special variant: "RO" redirects to Intel HEX loader (L command)
  94. ;
  95. ; MEMORY SET AND CALCULATION COMMANDS:
  96. ; • S AAAA DD - Set/Store data in memory (Entry: 0x063Fh)
  97. ; Store byte value DD at address AAAA, then continue
  98. ; Prompts for next address and value in sequence
  99. ; Interactive memory loading/initialization command
  100. ;
  101. ; • N - Next instruction execution/stepping (Entry: 0x049Fh)
  102. ; Single-step debugger instruction execution control
  103. ; Executes next instruction with debugging support
  104. ; Used for step-by-step program analysis and debugging
  105. ;
  106. ; • H XXXX YYYY - Hex arithmetic calculator (Entry: 0x0887h)
  107. ; Performs hex addition and subtraction on values XXXX and YYYY
  108. ; Displays both sum (XXXX + YYYY) and difference (XXXX - YYYY)
  109. ; Essential for address calculations and memory arithmetic
  110. ; Shows results in 4-digit hexadecimal format
  111. ;
  112. ; • T - Terminal echo/bridge mode (Entry: 0x014Fh)
  113. ; Bidirectional serial bridge between ports
  114. ; Creates infinite loop transferring data between serial interfaces
  115. ; Used for terminal echo, serial bridging, or communication testing
  116. ; Must be interrupted to return to monitor
  117. ;
  118. ; PORT I/O COMMANDS:
  119. ; • O D F T S - Floppy disk operation setup command (Entry: 0x09BCh)
  120. ; D = Drive number (0-3): Selects physical floppy drive A: through D:
  121. ; F = Flags (0-1): Drive control/head selection (0=standard, 1=alternate)
  122. ; T = Track (0-76): Track/cylinder number (max 77 tracks for 8" drives)
  123. ; S = Sectors (1-26): Sector count per operation (0=seek only, max 27)
  124. ; Note: O command only configures disk parameters, not memory addresses
  125. ; Examples: "O 0 0 5 1" configures drive A:, track 5, 1 sector
  126. ; "O 1 0 0 10" configures drive B:, track 0, 10 sectors
  127. ; Special: "OS" boots CP/M operating system from disk
  128. ;
  129. ; • P XXXX - Port I/O operations (Entry: 0x086Fh)
  130. ; Interactive I/O port read/write command
  131. ; P XXXX: Read from port XXXX, display value, prompt for new value
  132. ; Shows current port value, allows modification
  133. ; Special variant: PU goes to upload/checksum utility
  134. ;
  135. ; DATA TRANSFER COMMANDS:
  136. ; • U XXXX YYYY - Upload/Memory checksum utility (Entry: 0x0924h)
  137. ; Computes Intel HEX format checksums for memory range XXXX to YYYY
  138. ; Displays memory content in Intel HEX record format with checksums
  139. ; Essential for creating ROM images and data verification
  140. ; Output format: ":LLAAAATT[DD...]CC" where LL=length, AAAA=address,
  141. ; TT=type, DD=data bytes, CC=checksum. Handled by l0924h routine.
  142. ;
  143. ; • W AAAA BBBB - Write to disk/storage device (Entry: 0x09FAh)
  144. ; Write data from memory starting at AAAA with length BBBB to disk
  145. ; Uses disk parameters previously configured by O command
  146. ; Example: After "O 1 0 0 1", then "W 1000 100" writes 1 sector from 1000h
  147. ; [Command implementation requires further analysis]
  148. ;
  149. ; EXTENDED SYSTEM COMMANDS:
  150. ; • X - eXecute instruction analysis (Entry: 0x040Fh)
  151. ; Instruction analysis and breakpoint management
  152. ; Analyzes and executes instructions with debugging support
  153. ; Handles breakpoint restoration and instruction stepping
  154. ; Provides comprehensive register dump for program analysis
  155. ;
  156. ; ADDITIONAL COMMANDS:
  157. ; • Debug parameters can be configured via additional commands
  158. ; • Monitor supports commands: B,C,D,E,F,G,H,I,J,L,M,N,O,P,R,S,T,W,X
  159. ; • Use single letters followed by hex parameters as needed
  160. ; Values stored at 0x011D6 for various debugging modes
  161. ;
  162. ; SYSTEM MESSAGES:
  163. ; • "BREAK AT XXXX" - Displayed when execution breaks at address XXXX
  164. ; System returns to monitor prompt after breakpoints
  165. ;
  166. ; TECHNICAL FEATURES:
  167. ; • Sophisticated hex string parser supporting multi-parameter input
  168. ; • Intelligent input processing with space skipping and case conversion
  169. ; • Dual-purpose code/data sections for memory efficiency
  170. ; • Register state preservation and restoration
  171. ; • Interrupt mode 2 support with vector table
  172. ; • Advanced memory paging with 64KB external memory card
  173. ; • Professional error handling with graceful returns to command prompt
  174. ;
  175. ; CONTROL CHARACTERS:
  176. ; The monitor responds to standard terminal control characters for user control:
  177. ;
  178. ; • Ctrl+C (0x03 ETX) - Emergency System Reset/Break
  179. ; Immediately aborts current operation and returns to monitor
  180. ; Resets stack pointer and provides clean restart
  181. ; Similar to "break" functionality in modern terminals
  182. ; Works during any input operation or command execution
  183. ;
  184. ; • Ctrl+S (0x13 XOFF) - Pause/Resume Output Flow Control
  185. ; Temporarily pauses output display (standard XOFF)
  186. ; Press any key to resume output (XON behavior)
  187. ; Useful for stopping scrolling during long displays
  188. ; Standard terminal flow control implementation
  189. ;
  190. ; • Backspace (0x08) - Character Deletion During Input
  191. ; Deletes previous character from input buffer
  192. ; Echoes backspace-space-backspace sequence to terminal
  193. ; Provides visual feedback of character removal
  194. ; Standard line editing functionality
  195. ;
  196. ; • DEL (0x7F) - Alternative Character Deletion
  197. ; Functions identically to Backspace (0x08)
  198. ; Supports both common delete key encodings
  199. ; Maintains compatibility with different terminal types
  200. ;
  201. ; These control characters provide immediate user control over system operation
  202. ; and implement standard terminal behavior expected in professional systems.
  203. ;
  204. ; COMPREHENSIVE MEMORY MAP - Z80 METRIC 8 SYSTEM:
  205. ;==============================================================================
  206. ; ROM CODE SPACE:
  207. ; • 0x0000-0x0FFF: ROM Monitor/Debugger (4KB, 2x 2716 EPROM)
  208. ; Contains complete monitor system, command interpreter,
  209. ; disk I/O routines, debugging tools, and system initialization
  210. ;
  211. ; SYSTEM RAM LAYOUT:
  212. ; • 0x1000-0x10FF: User workspace (256 bytes) - Available for user programs/data
  213. ; • 0x1100-0x11FF: System I/O buffers and communication area (256 bytes)
  214. ; - 0x1100: SIO interrupt character buffer (keypress detection)
  215. ; - 0x1101-0x1102: Character timing measurement (16-bit, baud rate detection)
  216. ; - 0x1104: Console input buffer start (keyboard input processing)
  217. ; - 0x1168: Input processing buffer (temporary command storage)
  218. ; - 0x1169: Command input buffer (parsed command storage)
  219. ; - 0x11CD: Load/transfer address for L command operations
  220. ; - 0x11CF: Saved byte backup (breakpoint restoration storage)
  221. ; - 0x11D0: Breakpoint/execution counter for debugging
  222. ; - 0x11D1: Active breakpoint memory location (current breakpoint address)
  223. ; - 0x11D3: Original byte backup (saved from breakpoint location for restoration)
  224. ; - 0x11D4: Debug parameters and execution status storage
  225. ; - 0x11D6: Debug display parameters and mode settings
  226. ; - 0x11D7: Interrupt vector high byte for IM2 mode
  227. ; - 0x11D8: Complete register save area (AF,BC,DE,HL,IX,IY,SP) for user program execution
  228. ; - 0x11EA: Program execution start address (G/J commands)
  229. ; - 0x11EC: User stack pointer backup storage
  230. ; - 0x11EE: Saved debug parameters (temporary storage during execution)
  231. ; - 0x11F0: Current breakpoint address
  232. ; - 0x11F2: Console output buffer pointer (default: 0x1104)
  233. ; - 0x11F4: Input buffer current position pointer
  234. ; - 0x11F6: Current prompt character (0x2A='*', 0x3E='>', 0x20=' ')
  235. ; - 0x11F7: Disk operation ready flag (0xFF = ready, 0x00 = not ready)
  236. ; - 0x11F8: Disk operation function pointer (0x0DAB = read, 0x0DB1 = write)
  237. ;
  238. ; • 0x1200-0x12FF: Hardware configuration and disk I/O control (256 bytes)
  239. ; DISK CONTROLLER CONFIGURATION BLOCK (0x1200-0x1227):
  240. ; - 0x1200-0x1201: DMA buffer address (16-bit, set by R/W commands)
  241. ; - 0x1202: Drive number (0-3, configured by O command)
  242. ; - 0x1203: Drive status/ready flags (0x01 = ready, used for DMA config)
  243. ; - 0x1205-0x1206: Status counter A (16-bit, initialized to 0xFFFF)
  244. ; - 0x1207-0x1208: Status counter B (16-bit, initialized to 0xFFFF)
  245. ; - 0x1209: Sector size parameter (default: 0x24 = 36 bytes per sector)
  246. ; - 0x120A: I/O port configuration (0xF0 = FDC port base settings)
  247. ; - 0x120B: Drive count/mode (0x03 = 3 drives or mode 3)
  248. ; - 0x120C: Additional FDC configuration and status data
  249. ; - 0x120D: FDC status register (used by disk operation status validation)
  250. ; - 0x120E: FDC extended status register (used by error condition checking)
  251. ; - 0x1213: FDC command byte (0x03 = READ, 0x04 = write, 0x0F = seek)
  252. ; - 0x1214: Drive/head selection (computed from 0x1226 + 0x1202)
  253. ; - 0x1215-0x1218: Track/sector parameter table (4 bytes, copied from l0c98h):
  254. ; • 0x1215: Byte 0 - Base configuration (0x00)
  255. ; • 0x1216: Byte 1 - Timing setting (0x1A)
  256. ; • 0x1217: Byte 2 - Mode flags (0xED)
  257. ; • 0x1218: Byte 3 - Control settings (0xE5)
  258. ; - 0x1223: Disk operation parameter storage (used by data tables)
  259. ; - 0x1225: Track number (0-76, configured by O command)
  260. ; - 0x1226: Drive control flags (0-1, configured by O command)
  261. ; - 0x1227: Sector count (1-26, configured by O command)
  262. ; - 0x1228-0x122B: Disk parameter lookup table 1 (4 bytes, copied from l0c90h):
  263. ; • 0x1228: Byte 0 - Base configuration value (0x00)
  264. ; • 0x1229: Byte 1 - Drive timing/control setting (0x1A)
  265. ; • 0x122A: Byte 2 - Drive mode flags (0x20)
  266. ; • 0x122B: Byte 3 - Drive status/control flags (0x80)
  267. ; - 0x122C-0x1241: DMA configuration block (22 bytes/0x16, copied from l0cfbh):
  268. ; • 0x122C-0x122E: Data bytes 0-2 (0xC3, 0xC3, 0xC3)
  269. ; • 0x122F-0x1231: Data bytes 3-5 (0xC3, 0xC3, 0xC3)
  270. ; • 0x1232: Data byte 6 (0x79)
  271. ; • 0x1233-0x1237: Data bytes 7-10 (padding: 0x00, 0x00, 0x00, 0x00)
  272. ; • 0x1238: Data byte 11 (0x14)
  273. ; • 0x1239-0x123A: Data bytes 12-13 (0x28, 0x89)
  274. ; • 0x123B-0x123D: Data bytes 14-16 (0xF2, 0x82, 0x83)
  275. ; • 0x123E: Data byte 17 (0xCF)
  276. ; • 0x123F-0x1241: Data bytes 18-20 (0x01, 0x83, 0xCF)
  277. ;
  278. ; • 0x1240-0x124F: FDC operation status and buffer management
  279. ; - 0x1242: SIO serial port configuration pointer (points to table at 0x0507)
  280. ; - 0x1243: Serial port base address configuration byte (used by I/O routines)
  281. ; - 0x1244-0x1245: 16-bit buffer pointer (low bank) - cleared to 0x0000 at startup
  282. ; - 0x1246-0x1247: 16-bit buffer pointer (mid bank) - cleared to 0x0000 at startup
  283. ; - 0x1248-0x1249: 16-bit buffer pointer (high bank) - cleared to 0x0000 at startup
  284. ; - 0x124A: FDC operation completion status (0 = pending, non-zero = done)
  285. ; - 0x124B: Additional FDC status and control parameters
  286. ;
  287. ; • 0x1300-0x132F: Interrupt vector table (IM2 mode, 48 bytes)
  288. ; - Contains interrupt vectors for SIO, DMA, and FDC operations
  289. ; - 0x1326: Breakpoint address backup (for memory paging operations)
  290. ; - 0x1334: Interrupt vector table pointer (used by DMA completion handler)
  291. ;
  292. ; • 0x1400-0x1FFF: System stack and buffers (1.5KB)
  293. ; - 0x1400: Stack pointer initialization point (grows downward)
  294. ; - Stack used for monitor operations, command processing, and user programs
  295. ; - Available memory: 0x1700-0x1FFF (2304 bytes) for user programs/data
  296. ;
  297. ; BANKED MEMORY SYSTEM:
  298. ; • 0x2000-0x3FFF: Paged RAM window (8KB, bank-switched)
  299. ; Access to 64KB external memory card via 8KB window
  300. ; Page selection via ports 0x000/0x003 (3-bit page number 0-7)
  301. ; Enables access to total 64KB external RAM in 8KB pages
  302. ;
  303. ;==============================================================================
  304. ;
  305. ; DISK I/O DATA TABLES SUMMARY:
  306. ; ROM Tables copied to RAM during disk operations:
  307. ; • l0c90h (ROM) → 0x1228-0x122B (4 bytes): Disk parameter lookup table 1
  308. ; • l0c98h (ROM) → 0x1215-0x1218 (4 bytes): Track/sector parameter table
  309. ; • l0cfbh (ROM) → 0x122C-0x1241 (22 bytes): DMA configuration block
  310. ;
  311. ; Copy Operations performed by:
  312. ; • sub_0c73h: Copies l0c90h to 0x1228 (4 bytes via BC=0004h + LDIR)
  313. ; • sub_0c7bh: Copies l0c98h to 0x1215 (4 bytes via BC=0004h + LDIR)
  314. ; • Routine at 0cd7h: Copies l0cfbh to 0x122C (22 bytes via BC=0016h + LDIR)
  315. ;
  316. ;==============================================================================
  317. ;
  318. ; HARDWARE I/O PORT MAP:
  319. ;==============================================================================
  320. ; FLOPPY DISK CONTROLLER (NEC µPD765A):
  321. ; • Port 0xF0: FDC main status register (read-only)
  322. ; Bit 7: RQM (Request for Master) - FDC ready for command/data
  323. ; Bit 6: DIO (Data Input/Output) - Transfer direction
  324. ; Bit 5: NDM (Non-DMA Mode) - DMA/PIO mode indicator
  325. ; Bit 4: CB (Command Busy) - Command in progress
  326. ; Bits 0-3: Drive busy status (one bit per drive)
  327. ;
  328. ; • Port 0xF1: FDC data register (read/write)
  329. ; Command and parameter transfer port
  330. ; Data transfer during disk operations
  331. ;
  332. ; Z80 DMA CONTROLLER:
  333. ; • Port 0xF3: Z80 DMA command/status register (read/write)
  334. ; Used for high-speed disk data transfers
  335. ; Coordinates memory-to-peripheral data movement
  336. ;
  337. ; • Port 0xF4: Z80 DMA WR1 register (write-only)
  338. ; Memory address and byte count configuration
  339. ; Command 0x47: Address/count setup command
  340. ;
  341. ; • Port 0xF5: Z80 DMA WR3 register (write-only)
  342. ; Transfer mode, timing, and control settings
  343. ; Command 0x57: Transfer mode setup command
  344. ;
  345. ; • Port 0xFC: Z80 DMA controller command/parameter port
  346. ; Command 0x83: DMA control command for disk operations
  347. ; Used for DMA channel configuration and control
  348. ;
  349. ; MEMORY BANKING SYSTEM:
  350. ; • Port 0x000: Memory page selection (write-only)
  351. ; 3-bit page number (0-7) for 0x2000-0x3FFF window
  352. ; Enables access to 64KB external memory in 8KB pages
  353. ;
  354. ; • Port 0x003: Memory banking control (write-only)
  355. ; Additional banking control signals
  356. ; Used with port 0x000 for complete memory management
  357. ;
  358. ; SERIAL I/O CONTROLLER (SIO):
  359. ; • Ports 0x10-0x13: Z80 SIO/0 dual serial controller
  360. ; Channel A: Console terminal interface
  361. ; Channel B: Auxiliary serial port
  362. ; Supports interrupt-driven character I/O
  363. ; Automatic baud rate detection capability
  364. ;==============================================================================
  365. ; Used for programming the Z80 DMA with initialization sequences
  366. ; The hardware config table at 0x0F55 shows 19 bytes (count + 18 data bytes)
  367. ; written to this port to configure DMA operations
  368. ; Values 0x83/0xC3 are DMA command codes for control operations
  369. ;
  370. ; This monitor/debugger represents advanced 1980s software engineering with
  371. ; modular design, efficient algorithms, and professional user interface.
  372. ;
  373. ;##############################################################################
  374. ;Memory architecture:
  375. ;• 0x0000-0x0FFF: ROM code space (4KB 2716 EPROM)
  376. ;• 0x1000-0x13FF: Base RAM workspace (1KB)
  377. ;• 0x1242 SIO port config 0x0507
  378. ;• 0x1300-0x1320: Interrupt vector table (IM2 mode) from 0x024f
  379. ;• 0x1400: Stack pointer start (grows downward toward RAM)
  380. ;• 0x2000-0x3FFF: Paged RAM window (8KB, bank-switched)
  381. ;• Extended RAM: 8x 4164 chips = 8 pages × 8KB = 64KB total
  382. ;• Page switching: Hardware register selects active 8KB bank
  383. ;• Effective memory: 1KB base + 8KB paged window + ROM
  384. ;==============================================================================
  385. ; MEMORY PAGING SYSTEM DOCUMENTATION
  386. ;==============================================================================
  387. ; The Metric 8 system implements a sophisticated memory paging mechanism to
  388. ; access a 64KB external memory card through an 8KB window at 0x2000-0x3FFF.
  389. ;
  390. ; CLEVER PORT SHARING STRATEGY:
  391. ; The system exploits the fact that ROM code only uses CTC Channels 1 and 2,
  392. ; leaving Channels 0 and 3 unused. Memory paging "hijacks" these unused ports
  393. ; without conflicting with essential CTC timing functions.
  394. ;
  395. ; PORT ALLOCATION STRATEGY:
  396. ; • PORT 0x000 (CTC Channel 0): UNUSED by ROM → Available for memory control
  397. ; • PORT 0x001 (CTC Channel 1): Used by ROM for timing functions
  398. ; • PORT 0x002 (CTC Channel 2): Used by ROM for SIO baud rate generation
  399. ; • PORT 0x003 (CTC Channel 3): UNUSED by ROM → Available for page selection
  400. ;
  401. ; MEMORY ARCHITECTURE:
  402. ; • Base System RAM: 1KB at 0x1000-0x13FF (always accessible)
  403. ; • Paged Memory Window: 8KB at 0x2000-0x3FFF (bank-switched via ports 0x000/0x003)
  404. ; • External Memory Card: 64KB organized as 8 pages × 8KB each
  405. ; • Total Addressable Memory: 1KB + 64KB = 65KB (plus ROM)
  406. ;
  407. ; CONTROL PORTS:
  408. ; • PORT 0x000: Memory Management Control Register (hijacks unused CTC Channel 0)
  409. ; - Bit 5 (0x20): Enable paging system
  410. ; - Controls overall memory management subsystem
  411. ;
  412. ; • PORT 0x003: Page Selection Register (hijacks unused CTC Channel 3)
  413. ; - 3-bit page number (0-7) selects which 8KB page appears at 0x2000-0x3FFF
  414. ; - Sequential writes may configure additional memory features
  415. ;
  416. ; COEXISTENCE WITH STANDARD HARDWARE:
  417. ; This design allows memory paging to work with standard SIO/CTC configuration:
  418. ; • SIO: ports 0x04-0x07 (unchanged)
  419. ; • CTC Channels 1&2: ports 0x01-0x02 (unchanged, ROM functions preserved)
  420. ; • Memory Management: ports 0x000 & 0x003 (reuse of unused CTC channels)
  421. ; • Result: 64KB memory card works with standard I/O configuration!
  422. ;
  423. ; OBSERVED PORT OPERATIONS:
  424. ; 1. out (000h),20h ; Enable memory management (bit 5 = paging enable)
  425. ; 2. out (003h),87h ; Select page 7 with setup flags (page + control bits)
  426. ; 3. out (003h),01h ; Select page 1 for actual operation
  427. ; 4. out (003h),03h ; Select page 3 (restore/cleanup page)
  428. ;==============================================================================
  429. ;I/O subsystem:
  430. ;• SIO 8440 chip for serial console (Pin 15 TxDA, Pin 17 RxDA) port 05-07
  431. ;• MC1488/MC1489 RS-232 drivers (require ±12V)
  432. ;• CTC for baud rate generation and timing port 00-04
  433. ;• Z80 DMA controller for high-speed floppy transfers - port 0xF3
  434. ;• FDC NEC µPD765A for 8-inch floppy drives (77 tracks, 26 sectors/track):
  435. ; - 0xF0: FDC Main Status Register (read)
  436. ; - 0xF1: FDC Data Register (read/write via register C)
  437. ; - 0xF4: FDC Data Register (direct access)
  438. ; - 0xF6: FDC Command/Status Register
  439. ; - 0xFC: Additional FDC control
  440. ;• I/O ports accessed via register C
  441. org 00000h
  442. l0000h:
  443. jr l000eh ;0000 ; Boot entry: jump to initialization routine
  444. jp l00fdh ;0002 ; Main system routine (post-init)
  445. jp l0dabh ;0005 ; Error/exception handler or alternate entry
  446. jp l0294h ;0008 ; Memory test or hardware check
  447. jp l0de0h ;000b ; Interrupt/Z80 DMA handler or alternate
  448. l000eh:
  449. ld sp,01400h ;000e ; Set stack pointer to top of 1K SRAM (boot RAM)
  450. ld hl,01000h ;0011 ; HL points to start of SRAM
  451. ld de,01001h ;0014 ; DE points to next byte in SRAM
  452. ld bc,003ffh ;0017 ; BC = 1023 bytes (1K - 1)
  453. ld (hl),000h ;001a ; Zero first byte of SRAM
  454. ldir ;001c ; Zero entire 1K SRAM (boot RAM clear)
  455. ld a,013h ;001e ; Load interrupt vector base (IM2 table address)
  456. l0020h:
  457. ld i,a ;0020 ; Set Z80 interrupt vector register (IM2 base)
  458. im 2 ;0022 ; Set interrupt mode 2 (for SIO, Z80 DMA, FDC)
  459. call hw_init_01ach ;0024 ; Call hardware init (Z80 DMA, SIO, FDC setup)
  460. ld hl,l0507h ;0027 ; HL = pointer to boot string or table
  461. l002ah:
  462. jr nz,l002fh ;002a Fail hw test if it find some form of other thing then sio on port 04 06
  463. l002ch:
  464. ld hl,0c3c1h ;002c This should be an alternate SIO card
  465. l002fh:
  466. ld (01242h),hl ;002f ; Save HL (alternate pointer) at 01242h for later use
  467. ld a,l ;0032 ; Load low byte of HL into A (may be used for error handling)
  468. ld hl,linterruptvector_table ;0033 ; Set HL to interrupt vector table address
  469. jr l003bh ;0036 ; Continue with boot sequence (alternate path)
  470. jp l07bch ;0038 ; Jump to CP/M loader or main OS entry if needed
  471. l003bh:
  472. ld de,01300h ;003b ; DE = destination Interruptvector addres
  473. ld bc,l0020h ;003e ; BC = length to copy (from l0020h)
  474. ldir ;0041 ; Block copy: transfer BC bytes from HL to DE
  475. ld hl,setupsio_table ;0043 ; HL = pointer to primary SIO configuration table
  476. cp 007h ;0046 ; Compare A to 7 (hardware detection/boot status)
  477. jr z,l004dh ;0048 ; If A == 7, use primary SIO card (normal case)
  478. ld hl,00214h ;004a ; If not, use secondary SIO card at high port addresses (0xC0+)
  479. l004dh:
  480. call setup_peripherals_01a1h ;004d ; Initialize peripherals (SIO)
  481. push hl ;0050 ; Save HL (pointer or error address)
  482. ld hl,01100h ;0051 ; HL = system buffer or stack
  483. sub a ;0054 ; Clear A (set to zero)
  484. ld (hl),a ;0055 ; Zero system buffer
  485. ei ;0056 Enable interrupts ; ROM code space
  486. l0057h:
  487. or (hl) ;0057 OR accumulator A with memory contents at address HL ; ROM code space,wait for keypress
  488. jr z,l0057h ;0058 Jump relative if Z to 0x0057 ; ROM code space
  489. di ;005a
  490. call sub_0149h ;005b
  491. ld a,030h ;005e //WR= error reset
  492. out (c),a ;0060
  493. jr l0069h ;0062
  494. rst 38h ;0064
  495. rst 38h ;0065
  496. jp l07b3h ;0066 ; Jump to interrupt/error handler - displays "BREAK AT " message
  497. l0069h:
  498. call sub_015dh ;0069 ; Call automatic baud rate detection and SIO configuration
  499. ld a,(01242h) ;006c
  500. cp 007h ;006f
  501. ld c,002h ;0071 ; Set C to 0x02 (standard CTC port)
  502. jr z,l0077h ;0073
  503. ld c,0c4h ;0075 ; Set C to 0xC4 (alternate CTC port)
  504. l0077h:
  505. ;==============================================================================
  506. ; ADAPTIVE CTC CHANNEL INITIALIZATION (0x0079)
  507. ;==============================================================================
  508. ; Purpose: Configure CTC channel with automatic port selection and dual-phase setup
  509. ; Entry: sub_0079h - Called during hardware initialization sequence
  510. ;
  511. ; Input Registers:
  512. ; - A: 0x47 (CTC control word for initial configuration)
  513. ; - B: 0x02 (time constant value)
  514. ; - C: CTC port address (0x02 for standard, 0xC4 for alternate hardware)
  515. ;
  516. ; CTC Control Word 0x47 Breakdown:
  517. ; - Bit 7: 0 = Interrupt enable
  518. ; - Bit 6: 1 = Counter mode (not timer mode)
  519. ; - Bit 5: 0 = Prescaler ÷16
  520. ; - Bit 4: 0 = Positive edge trigger
  521. ; - Bit 3: 1 = Time constant follows command
  522. ; - Bit 2: 1 = Software reset active
  523. ; - Bits 1-0: 11 = Control word identifier
  524. ;
  525. ; Two-Phase Operation:
  526. ; PHASE 1 (0x0079-0x007D): Send control word and time constant
  527. ; PHASE 2 (0x0087-0x008D): Send final control word (0x47) and divisor (0x02)
  528. ;
  529. ; Port Selection Logic:
  530. ; - Compares value from 0x1242 with 0x07 (SIO Channel B Control port)
  531. ; - If 0x1242 = 0x07: Uses standard mapping, C = 0x02 (CTC Channel 2)
  532. ; - If 0x1242 ≠ 0x07: Uses alternate mapping, C = 0xC4 (alternate CTC port)
  533. ;
  534. ; Hardware Compatibility:
  535. ; - Standard: SIO at 0x04-0x07, CTC at 0x00-0x03, configures CTC Channel 2
  536. ; - Alternate: Different SIO ports, CTC at 0xC0-0xC7, configures alternate CTC
  537. ;
  538. ; Time Constant 0x02:
  539. ; - Divides input clock by 2
  540. ; - Used for SIO clock generation (baud rate timing)
  541. ; - Combined with ÷16 prescaler = total division of 32
  542. ;
  543. ; Integration: Part of larger peripheral initialization sequence
  544. ; Called after SIO detection and before final hardware setup
  545. ;==============================================================================
  546. ld a,047h ;0077
  547. sub_0079h:
  548. out (c),a ;0079 Send CTC control word (0x47) to selected port
  549. out (c),b ;007b Send time constant (0x02) to CTC channel
  550. ld a,c ;007d Copy port address to A for comparison
  551. cp 0xc4 ;007f Compare with 0xC4 (alternate hardware marker)
  552. jr z,0x0085 ;0080 If alternate hardware, jump to port adjustment
  553. dec c ;0082 Standard hardware: decrement to previous channel
  554. jr 0x0087 ;0083 Continue to phase 2 initialization
  555. ; Alternate hardware port adjustment
  556. inc c ;0085 Increment port (0xC4 → 0xC5)
  557. inc c ;0086 Increment port (0xC5 → 0xC6)
  558. ; Phase 2: Final CTC configuration
  559. l0087h:
  560. ld a,047h ;0087 Reload CTC control word
  561. out (c),a ;0089 Send control word to final port
  562. ld a,002h ;008b Load final time constant/divisor
  563. out (c),a ;008d Send final configuration to CTC
  564. ;==============================================================================
  565. ; PHASE 3: COMPLETE HARDWARE INITIALIZATION AND SIO TESTING (0x008F+)
  566. ;==============================================================================
  567. ; After CTC setup, complete remaining peripheral initialization and test SIO
  568. ;==============================================================================
  569. ; Continue table-driven peripheral initialization
  570. pop hl ;008f Restore HL from stack (pointer to init table)
  571. inc hl ;0090 Advance to next table entry
  572. call setup_peripherals_01a1h ;0091 Continue table-driven peripheral setup
  573. ; Load test parameters and call diagnostic routine
  574. ld bc,058c0h ;0094 Load test parameters: B=0x58 (count), C=0xC0 (port/data)
  575. call sub_0f0ah ;0097 Call diagnostic/test routine with parameters
  576. ; SIO port preparation and buffer clearing
  577. call sub_0149h ;009a Get SIO port configuration (loads C with SIO control port)
  578. dec c ;009d Convert to SIO data port (control port - 1)
  579. in a,(c) ;009e Read SIO data port (clear any pending RX data)
  580. in a,(c) ;00a0 Read SIO data port again (ensure buffer clear)
  581. in a,(c) ;00a2 Third read to fully flush RX buffer
  582. ; Test SIO transmission capability
  583. call sub_0121h ;00a4 Send test character via SIO (verify TX works)
  584. ; Second SIO buffer clearing after transmission test
  585. dec c ;00a7 Set C back to SIO data port
  586. in a,(c) ;00a8 Read SIO data port (clear any echo/response data)
  587. in a,(c) ;00aa Read SIO data port again (ensure clean state)
  588. in a,(c) ;00ac Third read to fully flush post-transmission buffer
  589. ; Hardware initialization complete - enable interrupts and continue
  590. ei ;00ae Enable interrupts (hardware now fully operational)
  591. ; Print startup message after successful hardware initialization
  592. ld hl,l00e5h ;00af Load pointer to "Self diagnostics ..." message
  593. call l00fdh ;00b2 Print the startup message via serial port
  594. ; Run comprehensive system diagnostics
  595. call sub_0e89h ;00b5 Execute full system diagnostic suite
  596. ;==============================================================================
  597. ; SYSTEM CONFIGURATION MEMORY INITIALIZATION (0x00B8-0x00DF)
  598. ;==============================================================================
  599. ; Purpose: Initialize critical system configuration variables after diagnostics
  600. ; This section sets up default values for system operation parameters
  601. ;==============================================================================
  602. ld a,001h ;00b8 Load configuration value 0x01
  603. ld (01203h),a ;00ba Store at 0x1203: Drive/status flags (bit 0 = drive ready)
  604. ld a,024h ;00bd Load configuration value 0x24 (36 decimal)
  605. ld (01209h),a ;00bf Store at 0x1209: Sector size parameter (36 bytes/sector?)
  606. ld a,0f0h ;00c2 Load configuration value 0xF0 (240 decimal)
  607. ld (0120ah),a ;00c4 Store at 0x120A: Port/channel configuration byte
  608. ld a,003h ;00c7 Load configuration value 0x03
  609. ld (0120bh),a ;00c9 Store at 0x120B: Drive count or operation mode
  610. ld hl,l0000h ;00cc Load 16-bit value 0x0000
  611. ld (01244h),hl ;00cf Store at 0x1244: Clear 16-bit buffer/pointer (low)
  612. ld (01246h),hl ;00d2 Store at 0x1246: Clear 16-bit buffer/pointer (mid)
  613. ld (01248h),hl ;00d5 Store at 0x1248: Clear 16-bit buffer/pointer (high)
  614. dec hl ;00d8 Decrement HL to 0xFFFF
  615. ld (01205h),hl ;00d9 Store at 0x1205: Initialize 16-bit counter/status (0xFFFF)
  616. ld (01207h),hl ;00dc Store at 0x1207: Initialize 16-bit counter/status (0xFFFF)
  617. call sub_0acbh ;00df Call additional hardware setup routine
  618. jp l0294h ;00e2 Jump to main system initialization
  619. ;==============================================================================
  620. ; STARTUP MESSAGE: "Self diagnostics ..."
  621. ;==============================================================================
  622. ; Displayed after successful hardware initialization to indicate system status
  623. ;==============================================================================
  624. l00e5h:
  625. defb "Self diagnostics ..." ;00e5-00f8 Startup message text
  626. defb 0xda ;00f9 Special character (Ú or box drawing)
  627. defb 0x0d ;00fa Carriage return
  628. defb 0x0a ;00fb Line feed
  629. defb 0x00 ;00fc Null terminator
  630. ;==============================================================================
  631. ; STRING OUTPUT ROUTINES - Console Display Functions
  632. ;==============================================================================
  633. ; Two different string output routines for different output methods
  634. ;==============================================================================
  635. ;==============================================================================
  636. ; PRINT STRING ROUTINE (0x00FD) - Standard Console Output
  637. ;==============================================================================
  638. ; Purpose: Print null-terminated string to console via standard output
  639. ; Input: HL = pointer to null-terminated string
  640. ; Output: String displayed on console via sub_0127h (console output with wait)
  641. ; Operation: Loops through string characters until null terminator found
  642. ; Used by: Main system messages, prompts, and user interface text
  643. ;==============================================================================
  644. l00fdh: ; Standard Print String Routine
  645. ld a,(hl) ;00fd Load character from string
  646. and a ;00fe Test for null terminator (sets Z flag if A=0)
  647. ret z ;00ff Return if end of string reached
  648. ld c,a ;0100 Move character to C register for output
  649. call sub_0127h ;0101 Call console output with wait (transmitter ready check)
  650. inc hl ;0104 Point to next character in string
  651. jr l00fdh ;0105 Loop back for next character
  652. ;==============================================================================
  653. ; ALTERNATE PRINT STRING ROUTINE (0x0107) - Direct Serial Output
  654. ;==============================================================================
  655. ; Purpose: Print null-terminated string via direct serial output method
  656. ; Input: HL = pointer to null-terminated string
  657. ; Output: String sent via sub_0111h (direct serial output)
  658. ; Operation: Similar to standard routine but uses different output method
  659. ; Used by: Low-level system messages or when console output unavailable
  660. ;==============================================================================
  661. l0107h: ; Alternate Print String Routine
  662. ld a,(hl) ;0107 Load character from string
  663. and a ;0108 Test for null terminator (sets Z flag if A=0)
  664. ret z ;0109 Return if end of string reached
  665. ld c,a ;010a Move character to C register for output
  666. call sub_0111h ;010b Call direct serial output routine
  667. inc hl ;010e Point to next character in string
  668. jr l0107h ;010f Loop back for next character
  669. ;==============================================================================
  670. ; DIRECT SERIAL OUTPUT ROUTINE (0x0111)
  671. ;==============================================================================
  672. ; Purpose: Output character directly to serial port without full handshaking
  673. ; Input: C = character to output
  674. ; Operation: Calls sub_0121h then jumps to l012ah for immediate transmission
  675. ;==============================================================================
  676. sub_0111h: ; Direct Serial Output
  677. call sub_0121h ;0111 Set up serial port configuration
  678. jr l012ah ;0114 Jump to immediate output routine
  679. ;==============================================================================
  680. ; SERIAL INPUT WITH WAIT (0x0116)
  681. ;==============================================================================
  682. ; Purpose: Wait for and read character from serial input
  683. ; Output: C = received character
  684. ; Operation: Loops until character available, then returns it
  685. ;==============================================================================
  686. l0116h: ; Serial Input with Wait
  687. call sub_011ch ;0116 Check for input character available
  688. jr z,l0116h ;0119 Loop if no character available (Z flag set)
  689. ret ;011b Return with character in C register
  690. ;==============================================================================
  691. ; CHECK SERIAL INPUT READY (0x011C)
  692. ;==============================================================================
  693. ; Purpose: Check if serial input character is available (non-blocking)
  694. ; Output: Z flag = set if no character, clear if character available
  695. ; C = character (if available)
  696. ; Operation: Tests serial port status and reads character if present
  697. ;==============================================================================
  698. sub_011ch: ; Check Serial Input Ready
  699. call sub_0121h ;011c Set up serial port configuration
  700. jr l013dh ;011f Jump to input status check routine
  701. ;==============================================================================
  702. ; SERIAL PORT SETUP ROUTINE (0x0121)
  703. ;==============================================================================
  704. ; Purpose: Set up serial port configuration for I/O operations
  705. ; Input: C = character to be output (preserved in B register)
  706. ; Output: C = serial port address from configuration byte at 0x1243
  707. ; Operation: Saves character, loads port address, prepares for I/O
  708. ;==============================================================================
  709. sub_0121h: ; Serial Port Setup
  710. ld b,c ;0121 Save character/input parameter in B register
  711. ld a,(01243h) ;0122 Load serial port base address from config byte
  712. l0125h:
  713. ld c,a ;0125 Move port address to C register
  714. ret ;0126 Return with port address in C, character in B
  715. ;ROUTINE: Console Output with Wait (0x0127)
  716. ;--------------------------------------------
  717. ;Purpose: Outputs character and waits for transmitter ready
  718. sub_0127h:
  719. call sub_0149h ;0127 Get serial port base address
  720. l012ah:
  721. in a,(c) ;012a Read status register
  722. bit 2,a ;012c Test transmitter ready bit
  723. jr z,l012ah ;012e Wait if not ready
  724. dec c ;0130 Point to data register
  725. out (c),b ;0131 Output character
  726. ret ;0133 Return to caller
  727. l0134h:
  728. call sub_013ah ;0134 Check for input character available
  729. jr z,l0134h ;0137 Loop if no character available (Z flag set)
  730. ret ;0139 Return with character received
  731. ;==============================================================================
  732. ; CHECK SERIAL INPUT READY (0x013A) - Non-blocking Input Status Check
  733. ;==============================================================================
  734. ; Purpose: Check if serial input character is available without blocking
  735. ; Output: Z flag = set if no character, clear if character available
  736. ; C = character data (if available), A = character (7-bit masked)
  737. ; Operation: Tests serial port RX status bit, reads and processes character
  738. ;==============================================================================
  739. sub_013ah: ; Check Serial Input Ready (Non-blocking)
  740. call sub_0149h ;013a Get serial port base address in C register
  741. l013dh: ; Input status check entry point
  742. in a,(c) ;013d Read status register from serial port
  743. bit 0,a ;013f Test bit 0 (receiver ready/character available)
  744. ret z ;0141 Return with Z flag set if no character available
  745. dec c ;0142 Decrement C to point to data register (status+1=data)
  746. in a,(c) ;0143 Read character from serial port data register
  747. and 07fh ;0145 Mask to 7 bits (remove parity/high bit)
  748. sub_0147h: ; Character processing entry point
  749. ld c,a ;0147 Store character in C register for caller
  750. ret ;0148 Return with character in both A and C registers
  751. ;==============================================================================
  752. ; GET SERIAL PORT BASE ADDRESS (0x0149) - Port Configuration Setup
  753. ;==============================================================================
  754. ; Purpose: Load serial port base address from configuration and set up registers
  755. ; Input: C = current value (preserved in B)
  756. ; Output: C = serial port base address, B = saved previous C value
  757. ; Operation: Loads port address from config pointer at 0x1242
  758. ;==============================================================================
  759. sub_0149h: ; Get Serial Port Base Address
  760. ld b,c ;0149 Save current C register value in B
  761. ld a,(01242h) ;014a Load serial port configuration from memory
  762. ld c,a ;014d Set C to serial port base address
  763. ret ;014e Return with port address in C, old value in B
  764. ;==============================================================================
  765. ; ECHO/BRIDGE MODE (0x014F) - Bidirectional Serial Bridge
  766. ;==============================================================================
  767. ; Purpose: Implement echo or serial bridge functionality between ports
  768. ; Operation: Infinite loop that transfers data bidirectionally
  769. ; Used for: Terminal echo, serial port bridging, or communication testing
  770. ;==============================================================================
  771. l014fh: ; Echo/Bridge Mode Entry Point
  772. call sub_013ah ;014f Check for input character from serial port
  773. call nz,sub_0111h ;0152 If character received, output it (echo/bridge)
  774. call sub_011ch ;0155 Check for input from alternate source
  775. call nz,sub_0127h ;0158 If character received, output via console
  776. jr l014fh ;015b Loop continuously (infinite bridge mode)
  777. ;==============================================================================
  778. ; AUTOMATIC BAUD RATE CALCULATOR AND SIO CONFIGURATOR (0x015D)
  779. ;==============================================================================
  780. ; Purpose: Dynamically calculate and configure SIO baud rate based on timing measurements
  781. ; Entry: sub_015dh - Called after serial character timing measurements
  782. ;
  783. ; Input Values:
  784. ; - 0x1100: 8-bit timing measurement (character bit timing)
  785. ; - 0x1101-0x1102: 16-bit timing measurement (character/timeout count)
  786. ;
  787. ; Algorithm:
  788. ; 1. SCALING PHASE:
  789. ; - Loads 16-bit timing value from 0x1101-0x1102 into HL
  790. ; - Multiplies HL by 8 (three left shifts) to scale timing value
  791. ; - Loads 8-bit measurement from 0x1100 into A
  792. ;
  793. ; 2. MAGNITUDE DETECTION:
  794. ; - Performs arithmetic right shifts on A while incrementing HL
  795. ; - Counts significant bits to determine timing magnitude
  796. ; - Stops when carry flag set (found first '1' bit)
  797. ; - Result: BC = scaled timing value for table lookup
  798. ;
  799. ; 3. TABLE LOOKUP:
  800. ; - Searches baud rate table at l0183h (contains standard timing values)
  801. ; - Each table entry: 16-bit timing threshold + 8-bit SIO divisor value
  802. ; - Finds best matching standard baud rate for measured timing
  803. ; - Uses binary search approach with carry flag comparison
  804. ;
  805. ; 4. SIO CONFIGURATION:
  806. ; - Returns A = 0x44 (SIO WR4 register value: 1 stop bit, 16x clock)
  807. ; - Returns B = clock divisor value from table
  808. ;
  809. ; Table Format (l0183h):
  810. ; Each 3-byte entry: [Low_Threshold] [High_Threshold] [SIO_Divisor]
  811. ; - Thresholds define timing ranges for standard baud rates
  812. ; - SIO_Divisor used in WR4 register for clock generation
  813. ;
  814. ; Auto-Detection Process:
  815. ; - System measures actual bit timing from incoming serial data
  816. ; - This routine converts measurements to appropriate SIO clock settings
  817. ; - Enables automatic baud rate detection without manual configuration
  818. ;
  819. ; Applications:
  820. ; - Auto-configure terminal connections
  821. ; - Adapt to different computer baud rates automatically
  822. ; - Robust serial communication without preset requirements
  823. ;
  824. ; Returns: A = 0x44 (WR4 value), B = clock divisor, timing configured
  825. ; Notes: Sophisticated floating-point-like integer math for 1980s hardware
  826. ;==============================================================================
  827. sub_015dh: ; Automatic Baud Rate Calculator Entry Point
  828. ld hl,(01101h) ;015d Load 16-bit timing measurement from memory
  829. ld a,(01100h) ;0160 Load 8-bit character timing measurement
  830. add hl,hl ;0163 Multiply HL by 8 (scale timing value)
  831. add hl,hl ;0164 Left shift 1: HL = HL * 2
  832. add hl,hl ;0165 Left shift 2: HL = HL * 4, total = original * 8
  833. l0166h: ; Magnitude detection loop
  834. sra a ;0166 Arithmetic right shift A (find first significant bit)
  835. inc hl ;0168 Increment HL counter for each bit shift
  836. jr nc,l0166h ;0169 Continue until carry set (found first '1' bit)
  837. ld c,l ;016b Store low byte of scaled timing in C
  838. ld b,h ;016c Store high byte of scaled timing in B (BC = timing)
  839. ld hl,l0183h ;016d Point to baud rate lookup table start
  840. sub a ;0170 Clear A register (will count table entries)
  841. l0171h: ; Table search loop
  842. inc a ;0171 Increment table entry counter
  843. ld e,(hl) ;0172 Load low byte of timing threshold from table
  844. inc hl ;0173 Move to next byte in table
  845. ld d,(hl) ;0174 Load high byte of timing threshold (DE = threshold)
  846. inc hl ;0175 Move to next table entry
  847. ex de,hl ;0176 Exchange: HL = threshold, DE = table pointer
  848. and a ;0177 Clear carry flag for subtraction
  849. sbc hl,bc ;0178 Compare threshold with measured timing (HL - BC)
  850. ex de,hl ;017a Restore: HL = table pointer, DE = difference
  851. inc hl ;017b Move to divisor byte in current table entry
  852. jr c,l0171h ;017c If threshold < timing, try next table entry
  853. dec hl ;017e Back up to divisor byte of matching entry
  854. ld b,(hl) ;017f Load SIO clock divisor value into B register
  855. ld a,044h ;0180 Load SIO WR4 register value (1 stop bit, 16x clock)
  856. ret ;0182 Return with A = WR4 value, B = clock divisor
  857. ;==============================================================================
  858. ; BAUD RATE DETECTION TABLE (0x0183-0x01A0)
  859. ;==============================================================================
  860. ; Format: Each 3-byte entry contains [Low_Limit] [High_Limit] [SIO_Divisor]
  861. ; Used by automatic baud rate detection routine at sub_015dh
  862. ; Entries ordered from fastest to slowest baud rates for binary search
  863. ;==============================================================================
  864. l0183h:
  865. ; Entry 1: High speed range
  866. defb 0x10, 0x01, 0x2C ;0183-0185 ; Limits: 0x0110-0x012C, Divisor: 0x2C (44)
  867. ; Entry 2:
  868. defb 0x5C, 0x00, 0x04 ;0186-0188 ; Limits: 0x005C-0x0004, Divisor: 0x04 (4)
  869. ; Entry 3:
  870. defb 0xBC, 0x00, 0x08 ;0189-018B ; Limits: 0x00BC-0x0008, Divisor: 0x08 (8)
  871. ; Entry 4:
  872. defb 0x7C, 0x01, 0x10 ;018C-018E ; Limits: 0x017C-0x0110, Divisor: 0x10 (16)
  873. ; Entry 5:
  874. defb 0xFC, 0x02, 0x20 ;018F-0191 ; Limits: 0x02FC-0x0220, Divisor: 0x20 (32)
  875. ; Entry 6:
  876. defb 0x05, 0x40, 0x70 ;0192-0194 ; Limits: 0x4005-0x7040, Divisor: 0x70 (112)
  877. ; Entry 7:
  878. defb 0x09, 0x80, 0x70 ;0195-0197 ; Limits: 0x8009-0x7080, Divisor: 0x70 (112)
  879. ; Entry 8:
  880. defb 0x0C, 0xA0, 0xFF ;0198-019A ; Limits: 0xA00C-0xFFA0, Divisor: 0xFF (255)
  881. ; Entry 9: Low speed range
  882. defb 0xFF, 0xFF, 0x00 ;019B-019D ; Limits: 0xFFFF-0x00FF, Divisor: 0x00 (0)
  883. ; Table terminator
  884. defb 0xFF, 0xFF ;019E-019F ; End marker
  885. defb 0x00 ;01A0 ; Padding/terminator
  886. setup_peripherals_01a1h:
  887. ld a,(hl) ;01a1 ; Load count from table (A = number of bytes to output)
  888. and a ;01a2 ; Test if count is zero
  889. ret z ;01a3 ; If zero, end of table, return
  890. ld b,a ;01a4 ; Set B = count
  891. inc hl ;01a5 ; Move to next table entry
  892. ld c,(hl) ;01a6 ; Load port number from table
  893. inc hl ;01a7 ; Move to data bytes
  894. otir ;01a8 ; Output B bytes from (HL) to port C, increment HL each time
  895. jr setup_peripherals_01a1h ;01aa ; Repeat for next table entry
  896. hw_init_01ach: ;Probably check if there is a perifle that can be read and write to which is not a SIO
  897. ld hl,initsio_l01d9h ;01ac ; HL = pointer to hardware register or test value
  898. call setup_peripherals_01a1h ;01af ; Call additional hardware init routine
  899. ld c,004h ;01b2 ; Set port C = 0x04 (SIO A data port)
  900. ld a,055h ;01b4 ; Load test pattern 0x55
  901. call check_peri_01d2h ;01b6 ; Output 0x55 to port 0x04 (SIO A data port)
  902. ret nz ;01b9 ; If error, return
  903. ld a,0aah ;01ba ; Load test pattern 0xAA
  904. call check_peri_01d2h ;01bc ; Output 0xAA to port 0x04 (SIO A data port)
  905. ret nz ;01bf ; If error, return
  906. ld a,055h ;01c0 ; Load test pattern 0x55
  907. ld c,006h ;01c2 ; Set port C = 0x06 (SIO B data port)
  908. call check_peri_01d2h ;01c4 ; Output 0x55 to port 0x06
  909. and 00fh ;01c7 ; Mask lower nibble (hardware check)
  910. ret nz ;01c9 ; If error, return
  911. ld a,0aah ;01ca ; Load test pattern 0xAA
  912. call check_peri_01d2h ;01cc ; Output 0xAA to port 0x06 (SIO B data port)
  913. and 00fh ;01cf ; Mask lower nibble (hardware check)
  914. ret ;01d1 ; Return (hardware init complete)
  915. check_peri_01d2h:
  916. out (c),a ;01d2 ; Output value in A to port C
  917. ld b,a ;01d4 ; Save value in B
  918. in a,(c) ;01d5 ; Read value back from port C into A
  919. xor b ;01d7 ; Compare read value with what was written
  920. ret ;01d8 ; Return
  921. initsio_l01d9h:
  922. ; PRIMARY SIO CARD initialization table (ports 0x04-0x07)
  923. ; This is the first/preferred SIO card on the bus
  924. defb 0x02 ;01d9 ; Count: 2 bytes to output
  925. defb 0x05 ;01da ; Port: 0x05 (Primary SIO Channel A Control)
  926. defb 0xCF ;01db ; Data byte 1: WR 7, SEND ABORT (SDLC), RESET Tx UNDERRUN/EOM LATCH
  927. defb 0x00 ;01dc ; Data byte 2: SYNC BIT 8-15 = 0
  928. defb 0x02 ;01dd ; Count: 2 bytes to output
  929. defb 0x07 ;01de ; Port: 0x07 (Primary SIO Channel B Control)
  930. defb 0xCF ;01df ; Data byte 1: WR 7, SEND ABORT (SDLC), RESET Tx UNDERRUN/EOM LATCH
  931. defb 0xF0 ;01e0 ; Data byte 2: Reset channel B sync bit 12-15
  932. defb 0x00 ;01e1 ; END marker
  933. setupsio_table:
  934. l01e2h:
  935. ; CTC setup for SIO timing
  936. defb 0x02 ;01e2 ; 2 bytes to output
  937. defb 0x02 ;01e3 ; CTC Channel 2 (provides clock for SIO)
  938. defb 0x47 ;01e4 ; CTC Control: Software reset, Time constant follows, Prescaler=16, Counter mode
  939. defb 0x01 ;01e5 ; Time constant = 1 (fast clock for SIO)
  940. ; PRIMARY SIO CHANNEL B (Console/Terminal) - Complete WR Configuration
  941. defb 0x11 ;01e6 ; 17 bytes to configure Channel B
  942. defb 0x07 ;01e7 ; Port 0x07 (Primary SIO Channel B Control)
  943. ; WR0 Commands and Register Selection
  944. defb 0x58 ;01e8 ; WR0: 01011000b = Channel Reset + Reset Rx CRC Checker
  945. defb 0x02 ;01e9 ; WR0: 00000010b = Select WR2 for next write
  946. defb 0x00 ;01ea ; WR2: Interrupt vector = 0x00 (disable interrupts)
  947. defb 0x04 ;01eb ; WR0: 00000100b = Select WR4 for next write
  948. defb 0x10 ;01ec ; WR4: 00010000b = 16x clock, No parity, 1 stop bit, No sync
  949. defb 0x15 ;01ed ; WR0: 00010101b = Select WR5 + Send Abort (SDLC mode prep)
  950. defb 0x84 ;01ee ; WR5: 10000100b = DTR active, 8 bits/char, Tx disabled initially, No RTS yet
  951. defb 0x03 ;01ef ; WR0: 00000011b = Select WR3 + Reset External Status interrupts
  952. defb 0xd2 ;01f0 ; WR3: 11010010b = Rx 8 bits, Enter Hunt Phase, Sync Char Load Inhibit, Rx disabled initially
  953. defb 0x06 ;01f1 ; WR0: 00000110b = Select WR6 for next write
  954. defb 0xff ;01f2 ; WR6: Sync Character bits 0-7 = 0xFF (sync pattern low byte)
  955. defb 0x07 ;01f3 ; WR0: 00000111b = Select WR7 for next write
  956. defb 0x0f ;01f4 ; WR7: Sync Character bits 8-15 = 0x0F (sync pattern high byte)
  957. defb 0x11 ;01f5 ; WR0: 00010001b = Select WR1 + Reset External Status interrupts
  958. defb 0x0c ;01f6 ; WR1: 00001100b = Status affects vector, Rx INT on first char or special condition
  959. defb 0x23 ;01f7 ; WR0: 00100011b = Select WR3 + Enable INT on next Rx char
  960. defb 0xd3 ;01f8 ; WR3: 11010011b = Rx Enable, 8 bits, Enter Hunt Phase, Sync Char Load Inhibit
  961. defb 0x00 ;01f9 ; END marker
  962. l01fa:
  963. ; PRIMARY SIO CHANNEL B (Console) - Simplified Setup for Normal Operation
  964. defb 0x0c ;01fa ; 12 bytes to configure Channel B for basic async operation
  965. defb 0x07 ;01fb ; Port 0x07 (Primary SIO Channel B Control)
  966. defb 0x18 ;01fc ; WR0: 00011000b = Channel Reset (clear all state)
  967. defb 0x02 ;01fd ; WR0: 00000010b = Select WR2 for next write
  968. defb 0x00 ;01fe ; WR2: Interrupt vector = 0x00 (no interrupts)
  969. defb 0x18 ;01ff ; WR0: 00011000b = Channel Reset (ensure clean state)
  970. defb 0x01 ;0200 ; WR0: 00000001b = Select WR1 for next write
  971. defb 0x04 ;0201 ; WR1: 00000100b = Status affects interrupt vector
  972. defb 0x04 ;0202 ; WR0: 00000100b = Select WR4 for next write
  973. defb 0x44 ;0203 ; WR4: 01000100b = 16x clock, 1 stop bit, No parity, 8 bits
  974. defb 0x03 ;0204 ; WR0: 00000011b = Select WR3 + Reset External Status
  975. defb 0xc1 ;0205 ; WR3: 11000001b = Rx Enable, 8 bits/char, No auto enables
  976. defb 0x05 ;0206 ; WR0: 00000101b = Select WR5
  977. defb 0xea ;0207 ; WR5: 11101010b = RTS, DTR, Tx Enable, 8 bits/char, Break
  978. ; PRIMARY SIO CHANNEL A (Auxiliary/Data) - Basic Setup
  979. defb 0x09 ;0208 ; 9 bytes to configure Channel A
  980. defb 0x05 ;0209 ; Port 0x05 (Primary SIO Channel A Control)
  981. defb 0x18 ;020a ; WR0: 00011000b = Channel Reset
  982. defb 0x01 ;020b ; WR0: 00000001b = Select WR1 for next write
  983. defb 0x00 ;020c ; WR1: 00000000b = No interrupts, no status affects vector
  984. defb 0x04 ;020d ; WR0: 00000100b = Select WR4 for next write
  985. defb 0x44 ;020e ; WR4: 01000100b = 16x clock, 1 stop bit, No parity, 8 bits
  986. defb 0x03 ;020f ; WR0: 00000011b = Select WR3 + Reset External Status
  987. defb 0xc1 ;0210 ; WR3: 11000001b = Rx Enable, 8 bits/char
  988. defb 0x05 ;0211 ; WR0: 00000101b = Select WR5
  989. defb 0xea ;0212 ; WR5: 11101010b = RTS, DTR, Tx Enable, 8 bits/char, Break
  990. defb 0x00 ;0213 ; END marker
  991. l0214h:
  992. ; SECONDARY SIO CARD initialization table (ports 0xC0-0xC4)
  993. ; This is an alternate SIO card on the bus, used if primary SIO fails
  994. defb 0x02 ;0214 ; 2 bytes to output
  995. defb 0x02 ;0215 ; CTC channel (shared timing for secondary SIO)
  996. defb 0x47 ;0216 ; CTC Control: SW reset, Time constant follows, Prescaler=16, Counter mode
  997. defb 0x04 ;0217 ; Time constant = 4 (different timing from primary)
  998. defb 0x02 ;0218 ; 2 bytes to output
  999. defb 0xc4 ;0219 ; Port 0xC4 (Secondary SIO Channel A Control - high address mapping)
  1000. defb 0x47 ;021a ; Command: 01000111b = Select WR4 + Software reset + Time constant
  1001. defb 0x01 ;021b ; Parameter value
  1002. ; SECONDARY SIO CHANNEL B (Console backup) - Initial Setup
  1003. defb 0x05 ;021c ; 5 bytes to output
  1004. defb 0xc3 ;021d ; Port 0xC3 (Secondary SIO Channel B Control - high address mapping)
  1005. defb 0x58 ;021e ; WR0: 01011000b = Channel Reset + Reset Rx CRC Checker
  1006. defb 0x02 ;021f ; WR0: 00000010b = Select WR2 for next write
  1007. defb 0x10 ;0220 ; WR2: Interrupt vector = 0x10 (different from primary)
  1008. defb 0x01 ;0221 ; WR0: 00000001b = Select WR1 for next write
  1009. defb 0x04 ;0222 ; WR1: 00000100b = Status affects interrupt vector
  1010. ; SECONDARY SIO CHANNEL A (Data backup) - Complete Configuration
  1011. defb 0x0f ;0223 ; 15 bytes to output (extensive SIO configuration)
  1012. defb 0xc1 ;0224 ; Port 0xC1 (Secondary SIO Channel A Control - high address mapping)
  1013. defb 0x58 ;0225 ; WR0: 01011000b = Channel Reset + Reset Rx CRC Checker
  1014. defb 0x04 ;0226 ; WR0: 00000100b = Select WR4 for next write
  1015. defb 0x10 ;0227 ; WR4: 00010000b = 16x clock, No parity, 1 stop bit
  1016. defb 0x15 ;0228 ; WR0: 00010101b = Select WR5 + Send Abort (SDLC prep)
  1017. defb 0x84 ;0229 ; WR5: 10000100b = DTR active, 8 bits/char, Tx disabled initially
  1018. defb 0x03 ;022a ; WR0: 00000011b = Select WR3 + Reset External Status
  1019. defb 0xd2 ;022b ; WR3: 11010010b = Rx 8 bits, Enter Hunt Phase, Sync Char Load Inhibit
  1020. defb 0x06 ;022c ; WR0: 00000110b = Select WR6 for next write
  1021. defb 0xFF ;022d ; WR6: Sync Character bits 0-7 = 0xFF
  1022. defb 0x07 ;022e ; WR0: 00000111b = Select WR7 for next write
  1023. defb 0x0f ;022f ; WR7: Sync Character bits 8-15 = 0x0F
  1024. defb 0x11 ;0230 ; WR0: 00010001b = Select WR1 + Reset External Status
  1025. defb 0x0c ;0231 ; WR1: 00001100b = Status affects vector, Rx INT on first char
  1026. defb 0x23 ;0232 ; WR0: 00100011b = Select WR3 + Enable INT on next Rx char
  1027. defb 0xd3 ;0233 ; WR3: 11010011b = Rx Enable, 8 bits, Enter Hunt Phase
  1028. defb 0x00 ;0234 ; END marker
  1029. l0235h:
  1030. ; SECONDARY SIO - Final Configuration for Normal Operation
  1031. ; Simplified setup for basic async operation on backup SIO card
  1032. defb 0x0c ;0235 ; 12 bytes to output
  1033. defb 0xc3 ;0236 ; Port 0xC3 (Secondary SIO Channel B Control)
  1034. defb 0x18 ;0237 ; WR0: 00011000b = Channel Reset (clear all state)
  1035. defb 0x02 ;0238 ; WR0: 00000010b = Select WR2 for next write
  1036. defb 0x10 ;0239 ; WR2: Interrupt vector = 0x10 (secondary interrupt vector)
  1037. defb 0x18 ;023a ; WR0: 00011000b = Channel Reset (ensure clean state)
  1038. defb 0x01 ;023b ; WR0: 00000001b = Select WR1 for next write
  1039. defb 0x04 ;023c ; WR1: 00000100b = Status affects interrupt vector
  1040. defb 0x04 ;023d ; WR0: 00000100b = Select WR4 for next write
  1041. defb 0x44 ;023e ; WR4: 01000100b = 16x clock, 1 stop bit, No parity, 8 bits
  1042. defb 0x03 ;023f ; WR0: 00000011b = Select WR3 + Reset External Status
  1043. defb 0xc1 ;0240 ; WR3: 11000001b = Rx Enable, 8 bits/char, No auto enables
  1044. defb 0x05 ;0241 ; WR0: 00000101b = Select WR5
  1045. defb 0xea ;0242 ; WR5: 11101010b = RTS, DTR, Tx Enable, 8 bits/char, Break
  1046. ; SECONDARY SIO CHANNEL A - Basic Setup
  1047. defb 0x09 ;0243 ; 9 bytes to output
  1048. defb 0xc1 ;0244 ; Port 0xC1 (Secondary SIO Channel A Control)
  1049. defb 0x18 ;0245 ; WR0: 00011000b = Channel Reset
  1050. defb 0x01 ;0246 ; WR0: 00000001b = Select WR1 for next write
  1051. defb 0x00 ;0247 ; WR1: 00000000b = No interrupts, no status affects vector
  1052. defb 0x04 ;0248 ; WR0: 00000100b = Select WR4 for next write
  1053. defb 0x44 ;0249 ; WR4: 01000100b = 16x clock, 1 stop bit, No parity, 8 bits
  1054. defb 0x03 ;024a ; WR0: 00000011b = Select WR3 + Reset External Status
  1055. defb 0xc1 ;024b ; WR3: 11000001b = Rx Enable, 8 bits/char
  1056. defb 0x05 ;024c ; WR0: 00000101b = Select WR5
  1057. defb 0xea ;024d ; WR5: 11101010b = RTS, DTR, Tx Enable, 8 bits/char, Break
  1058. defb 0x00 ;024e ; END marker
  1059. ;==============================================================================
  1060. ; INTERRUPT VECTOR TABLE FOR SIO OPERATIONS
  1061. ;==============================================================================
  1062. ; These vectors are loaded into RAM at 0x1300+ for interrupt mode 2 operation
  1063. ; Provides specific handlers for different SIO interrupt conditions
  1064. ;==============================================================================
  1065. defb 0x91 ;024f ; Interrupt vector base (0x1300)
  1066. defb 0x02 ;0250 ; Interrupt linterupt2vector 0x1301
  1067. defb 0x92 ;0251 ; Interrupt vector 0x1302
  1068. defb 0x02 ;0252 ; Interrupt linterupt2vector 0x1303
  1069. defb 0x6f ;0253 ; Interrupt vector 0x1304
  1070. defb 0x02 ;0254 ; Interrupt linterupt1vector 0x1305
  1071. defb 0x91 ;0255 ; Interrupt vector 0x1306
  1072. defb 0x02 ;0256 ; Interrupt linterupt2vector 0x1307
  1073. defb 0x91 ;0257 ; Interrupt vector 0x1308
  1074. defb 0x02 ;0258 ; Interrupt linterupt2vector 0x1309
  1075. defb 0x91 ;0259 ; Interrupt vector 0x130a
  1076. defb 0x02 ;025a ; Interrupt linterupt2vector 0x130b
  1077. defb 0x91 ;025b ; Interrupt vector 0x130c
  1078. defb 0x02 ;025c ; Interrupt linterupt2vector 0x130d
  1079. defb 0x91 ;025d ; Interrupt vector 0x130e
  1080. defb 0x02 ;025e ; Interrupt linterupt2vector 0x130f
  1081. defb 0x91 ;025f ; Interrupt vector 0x1310
  1082. defb 0x02 ;0260 ; Interrupt linterupt2vector 0x1311
  1083. defb 0x91 ;0261 ; Interrupt vector 0x1312
  1084. defb 0x02 ;0262 ; Interrupt linterupt2vector 0x1313
  1085. defb 0x91 ;0263 ; Interrupt vector 0x1314
  1086. defb 0x02 ;0264 ; Interrupt linterupt2vector 0x1315
  1087. defb 0x91 ;0265 ; Interrupt vector 0x1316
  1088. defb 0x02 ;0266 ; Interrupt linterupt2vector 0x1317
  1089. defb 0x91 ;0267 ; Interrupt vector 0x1318
  1090. defb 0x02 ;0268 ; Interrupt linterupt2vector 0x1319
  1091. defb 0x91 ;0269 ; Interrupt vector 0x1320
  1092. defb 0x02 ;026A ; Interrupt linterupt2vector 0x1321
  1093. defb 0x6f ;026B ; Interrupt vector 0x1322
  1094. defb 0x02 ;026C ; Interrupt linterupt1vector 0x1323
  1095. defb 0x91 ;026D ; Interrupt vector 0x1324
  1096. defb 0x02 ;026E ; Interrupt linterupt2vector 0x1325
  1097. linterupt1:
  1098. push af ;026f ; Save accumulator and flags
  1099. push bc ;0270 ; Save BC register pair
  1100. call sub_0149h ;0271 ; Setup: loads serial port address into C (from 0x1242), C=command/status port
  1101. push hl ;0274 ; Save HL register pair
  1102. ld hl,l0000h ;0275 ; HL = 0 (used as a counter for timeout/retries)
  1103. l0278h:
  1104. dec c ;0278 ; C = C - 1 (now C=data port)
  1105. in a,(c) ;0279 ; Read data register from port C
  1106. or a ;027b ; Set flags based on A (is data nonzero?)
  1107. jr nz,l0288h ;027c ; If data != 0, jump to l0288h (data ready)
  1108. inc hl ;027e ; HL = HL + 1 (increment timeout/retry counter)
  1109. inc c ;027f ; C = C + 1 (restore C to command/status port,)
  1110. l0280h:
  1111. in a,(c) ;0280 ; Read command/status register from port C,
  1112. bit 0,a ;0282 ; Test bit 0 (is data available/ready) Rx CHARACTER AVAILABLE
  1113. jr nz,l0278h ;0284 ; If bit 0 set, go back to data port read
  1114. jr l0280h ;0286 ; Otherwise, keep polling command/status port
  1115. l0288h:
  1116. ld (01100h),a ;0288 ; Store received byte in 0x1100
  1117. ld (01101h),hl ;028b ; Store HL (timeout/retry count) in 0x1101/0x1102
  1118. pop hl ;028e ; Restore HL (was used as counter)
  1119. pop bc ;028f ; Restore BC
  1120. pop af ;0290 ; Restore AF
  1121. linterupt2:
  1122. ei ;0291 ; Enable interrupts
  1123. reti ;0292 ; Return from interrupt
  1124. ; --------------------------------------------------
  1125. ; 0x0294: System Initialization Block
  1126. ; - Sets stack pointer to 0x1400
  1127. ; - Loads interrupt vector (A=0x13), sets I register
  1128. ; - Sets interrupt mode 2 and enables interrupts
  1129. ; - Calls sub_0770h to save CPU context and further setup
  1130. ; --------------------------------------------------
  1131. l0294h:
  1132. ld sp,01400h ;0294
  1133. ld a,013h ;0297
  1134. ld i,a ;0299
  1135. im 2 ;029b
  1136. ei ;029d
  1137. call sub_0770h ;029e
  1138. ; --------------------------------------------------
  1139. ; After 0x029e: Continued System/Memory Initialization
  1140. ; - Sets HL to 01100h, stores at 011ech
  1141. ; - Sets HL to l0000h, stores at 011f0h
  1142. ; - Sets HL to l0fech, calls l00fdh (setup/copy routine)
  1143. ; - Sets HL to 01104h, stores at 011f2h
  1144. ; - Loads A with 0x2A, stores at 011f6h
  1145. ; - Calls sub_080dh (setup/test routine)
  1146. ; - Branches: if NZ, jumps to l02c9h; else, jumps to l0fbbh
  1147. ; Purpose: Finalizes pointers, memory, and hardware setup, then tests/branches on result
  1148. ; --------------------------------------------------
  1149. ld hl,01100h ;02a1
  1150. ld (011ech),hl ;02a4
  1151. ld hl,l0000h ;02a7
  1152. ld (011f0h),hl ;02aa
  1153. ld hl,l0fech ;02ad Load HL with address of version string ("Ver 1.2x 8 inch")
  1154. call l00fdh ;02b0 Print version string to console via standard output routine
  1155. ld hl,01104h ;02b3 Set HL to console buffer address (0x1104)
  1156. ld (011f2h),hl ;02b6 Store console buffer pointer at 0x011F2
  1157. ld a,02ah ;02b9
  1158. ld (011f6h),a ;02bb
  1159. call sub_080dh ;02be
  1160. jr nz,l02c9h ;02c1
  1161. jp l0fbbh ;02c3
  1162. l02c6h:
  1163. call sub_080dh ;02c6 Get user input from console
  1164. l02c9h:
  1165. call sub_02e4h ;02c9 Execute parsed command (dual-purpose code)
  1166. ; =============================================================================
  1167. ; MAIN MONITOR COMMAND LOOP - Heart of the Debug System
  1168. ; =============================================================================
  1169. ; Purpose: Main command prompt and processing loop for the monitor/debugger
  1170. ; Operation: Sets up input buffer, displays '>' prompt, processes commands
  1171. ; Flow: All monitor commands (dump, compare, breakpoint, etc.) return here
  1172. ; This is the central control point of the entire monitor system
  1173. ; =============================================================================
  1174. l02cch: ; Main Monitor Command Loop Entry Point
  1175. ld hl,01104h ;02cc Point to console input buffer start
  1176. ld (011f2h),hl ;02cf Store input buffer pointer for system use
  1177. ld a,03eh ;02d2 Load '>' character (0x3E = ASCII prompt)
  1178. ld (011f6h),a ;02d4 Store prompt character for display
  1179. jr l02c6h ;02d7 Jump to input processing (creates command loop)
  1180. l02d9h:
  1181. ld sp,01400h ;02d9
  1182. ld hl,l0323h ;02dc
  1183. call l00fdh ;02df
  1184. jr l02cch ;02e2
  1185. ;==============================================================================
  1186. ; DUAL-PURPOSE CODE/DATA TABLE (0x02E4-0x0322)
  1187. ;==============================================================================
  1188. ; This section serves as BOTH executable code AND data table!
  1189. ;
  1190. ; AS EXECUTABLE CODE (when called from 0x02C9):
  1191. ; - 0x02E4: CD 4C 06 call sub_064ch
  1192. ; - 0x02E7: 13 inc de
  1193. ; - 0x02E8: 42 ld b,d
  1194. ; - 0x02E9: E2 03 43 jp po,4303h
  1195. ; - etc.
  1196. ;
  1197. ; AS DATA TABLE (when accessed as bytes):
  1198. ; Contains ASCII character sequence B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,W,X
  1199. ; This appears to be a character encoding or command lookup table
  1200. ;
  1201. ; This technique was common in 1980s ROMs to save precious memory space
  1202. ; by making code serve dual purposes as both instructions and data
  1203. ;==============================================================================
  1204. sub_02e4h: ; Entry point when called as subroutine
  1205. call sub_064ch ;02e4 CD 4C 06
  1206. ; =============================================================================
  1207. ; COMMAND TABLE - Monitor Command Lookup Table
  1208. ; =============================================================================
  1209. ; Purpose: Table of valid monitor commands with their handler addresses
  1210. ; Structure: Count byte, followed by entries of (ASCII char, address low, address high)
  1211. ; Used by: sub_064ch to parse and dispatch monitor commands
  1212. ; =============================================================================
  1213. command_table:
  1214. defb 015h ;02e7 Command count (21 commands)
  1215. defb 042h ;02e8 'B' (ASCII 'B')
  1216. defb 0e2h, 003h ;02e9 Address 0x03e2 for B command
  1217. defb 043h ;02eb 'C' (ASCII 'C')
  1218. defb 023h, 003h ;02ec Address 0x0323 for C command
  1219. defb 044h ;02ee 'D' (ASCII 'D')
  1220. defb 058h, 003h ;02ef Address 0x0358 for D command
  1221. defb 045h ;02f1 'E' (ASCII 'E')
  1222. defb 015h, 005h ;02f2 Address 0x0515 for E command
  1223. defb 046h ;02f4 'F' (ASCII 'F')
  1224. defb 0b7h, 003h ;02f5 Address 0x03b7 for F command
  1225. defb 047h ;02f7 'G' (ASCII 'G')
  1226. defb 04ah, 004h ;02f8 Address 0x044a for G command
  1227. defb 048h ;02fa 'H' (ASCII 'H')
  1228. defb 087h, 008h ;02fb Address 0x0887 for H command
  1229. defb 049h ;02fd 'I' (ASCII 'I')
  1230. defb 0cfh, 003h ;02fe Address 0x03cf for I command
  1231. defb 04ah ;0300 'J' (ASCII 'J')
  1232. defb 041h, 004h ;0301 Address 0x0441 for J command
  1233. defb 04ch ;0303 'L' (ASCII 'L')
  1234. defb 09fh, 008h ;0304 Address 0x089f for L command
  1235. defb 04dh ;0306 'M' (ASCII 'M')
  1236. defb 0fch, 004h ;0307 Address 0x04fc for M command
  1237. defb 04eh ;0309 'N' (ASCII 'N')
  1238. defb 09fh, 004h ;030a Address 0x049f for N command
  1239. defb 04fh ;030c 'O' (ASCII 'O')
  1240. defb 0bch, 009h ;030d Address 0x09bc for O command
  1241. defb 050h ;030f 'P' (ASCII 'P')
  1242. defb 06fh, 008h ;0310 Address 0x086f for P command
  1243. defb 052h ;0312 'R' (ASCII 'R')
  1244. defb 0ffh, 009h ;0313 Address 0x09ff for R command
  1245. defb 053h ;0315 'S' (ASCII 'S')
  1246. defb 03fh, 006h ;0316 Address 0x063f for S command
  1247. defb 054h ;0318 'T' (ASCII 'T')
  1248. defb 04fh, 001h ;0319 Address 0x014f for T command
  1249. defb 057h ;031b 'W' (ASCII 'W')
  1250. defb 0fah, 009h ;031c Address 0x09fa for W command
  1251. defb 058h ;031e 'X' (ASCII 'X')
  1252. defb 00fh, 004h ;031f Address 0x040f for X command
  1253. defb 03fh ;0321 '?' (ASCII '?')
  1254. defb 000h ;0322 NULL terminator
  1255. ; =============================================================================
  1256. ; MEMORY COMPARE COMMAND (C command) - Monitor/Debugger Function
  1257. ; =============================================================================
  1258. ; Purpose: Compare two memory regions and display any differences
  1259. ; Input: User enters hex addresses via console (C start1 end1 start2)
  1260. ; Example: "C 1000 10FF 2000" compares memory 1000-10FF with 2000-20FF
  1261. ; Operation: Compares memory at [start1..end1] with memory starting at start2
  1262. ; Output: Shows mismatched bytes with both addresses and different values
  1263. ; Silent operation if regions are identical (no output = blocks match)
  1264. ; Error handling: Returns to monitor prompt on invalid input or completion
  1265. ; Used by: Monitor command interpreter for memory debugging and verification
  1266. ; =============================================================================
  1267. l0323h: ; Memory Compare Command Entry Point
  1268. call sub_0760h ;0323 Parse 3 hex addresses from user input (start1, end1, start2)
  1269. jp z,l02d9h ;0326 Jump to error handler if hex parsing failed
  1270. ex de,hl ;0329 DE=start1, HL=start2 (swap for comparison loop setup)
  1271. l032ah: ; Main Memory Comparison Loop
  1272. call sub_09a3h ;032a Check for keyboard input (allows user to abort with any key)
  1273. ld a,(de) ;032d Load byte from first memory region (source)
  1274. cp (hl) ;032e Compare with byte from second memory region (destination)
  1275. call nz,sub_0338h ;032f If bytes differ, display the mismatch details
  1276. inc de ;0332 Move to next byte in first region (source++)
  1277. cpi ;0333 CP (HL), INC HL, DEC BC - auto-increment second region
  1278. ret po ;0335 Return when BC=0 (all bytes compared, PO=parity odd/BC=0)
  1279. jr l032ah ;0336 Continue comparison loop until all bytes checked
  1280. ; =============================================================================
  1281. ; MEMORY MISMATCH DISPLAY HANDLER
  1282. ; =============================================================================
  1283. ; Purpose: Display details when memory comparison finds a difference
  1284. ; Input: DE=address in first region, HL=address in second region, A=(DE), (HL) differ
  1285. ; Output: Displays both addresses and their differing byte values
  1286. ; Format: Shows both addresses with their different values for user analysis
  1287. ; Example output might be: "1000: 42 2000: 24" (showing the mismatch)
  1288. ; =============================================================================
  1289. sub_0338h: ; Memory Mismatch Display Handler
  1290. push de ;0338 Save first region address on stack
  1291. call sub_0346h ;0339 Display first address and its byte value (format: "ADDR: XX")
  1292. ex (sp),hl ;033c Swap: HL=first addr (from stack), stack=second addr
  1293. call sub_0346h ;033d Display second address and its byte value (format: "ADDR: YY")
  1294. call sub_072ah ;0340 Output formatting/newline routine (complete the line)
  1295. ex de,hl ;0343 Restore proper register order (DE=first, HL=second)
  1296. pop hl ;0344 Restore second region address from stack
  1297. ret ;0345 Return to comparison loop
  1298. ; =============================================================================
  1299. ; ADDRESS AND BYTE VALUE DISPLAY ROUTINE
  1300. ; =============================================================================
  1301. ; Purpose: Display an address followed by the byte value at that address
  1302. ; Input: HL=memory address to display
  1303. ; Output: Shows "ADDR: XX" format to console
  1304. ; Used by: Memory compare, memory dump, and other debugging commands
  1305. ; =============================================================================
  1306. sub_0346h: ; Display Address and Byte Value
  1307. push hl ;0346 Save address
  1308. ld a,(hl) ;0347 Load byte value from address
  1309. push af ;0348 Save the byte value
  1310. call sub_06b8h ;0349 Display the address (HL) in hex
  1311. ld hl,(011f2h) ;034c Get console output buffer pointer
  1312. dec hl ;034f Back up one position
  1313. ld (hl),03dh ;0350 Insert '=' character (0x3D = ASCII '=')
  1314. pop af ;0352 Restore byte value
  1315. call sub_06c6h ;0353 Display byte value in hex
  1316. pop hl ;0356 Restore address
  1317. ret ;0357 Return
  1318. call sub_0763h ;0358
  1319. jr z,l03a0h ;035b
  1320. exx ;035d
  1321. ; =============================================================================
  1322. ; MEMORY DUMP/HEX DISPLAY COMMAND - 32 Bytes per Screen
  1323. ; =============================================================================
  1324. ; Purpose: Display memory contents in hex dump format (D command)
  1325. ; Input: Starting address in HL' (alternate register set)
  1326. ; Output format: XXXX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX *................*
  1327. ; Where: XXXX = 4-digit hex address, XX = hex bytes, * = ASCII representation
  1328. ; Block size: 16 bytes per line, 2 lines = 32 bytes total per screen
  1329. ; User can press any key to abort display and return to monitor
  1330. ; =============================================================================
  1331. l035eh: ; Memory Dump Command Entry Point
  1332. call sub_09a3h ;035e Check for keyboard input/break (allows user abort)
  1333. ld hl,01104h ;0361 Point to display buffer start (console buffer workspace)
  1334. ld de,01105h ;0364 Point to buffer start + 1 (for block fill operation)
  1335. ld bc,00049h ;0367 Set count = 73 bytes to clear (full display line + margin)
  1336. ld (hl),020h ;036a Put space character (0x20) in first position of buffer
  1337. ldir ;036c Fill entire buffer with spaces (clear display workspace)
  1338. ld b,010h ;036e Set counter for 16 bytes per line (standard hex dump width)
  1339. ld hl,01139h ;0370 Point to ASCII display area in buffer (right side of display)
  1340. ld (hl),02ah ;0373 Put '*' character as left ASCII area separator
  1341. inc hl ;0375 Move to first ASCII character position
  1342. exx ;0376 Switch to alternate register set (HL'=current memory address)
  1343. call sub_06b8h ;0377 Display 4-digit hex address at line start (XXXX format)
  1344. l037ah: ; Main byte display loop (16 bytes per line)
  1345. ld a,(hl) ;037a Load byte from current memory address
  1346. exx ;037b Switch to buffer registers (for ASCII display area)
  1347. ld (hl),a ;037c Store byte in ASCII display area (right side preview)
  1348. cp 020h ;037d Compare with space character (0x20)
  1349. jr c,l0385h ;037f If < 0x20 (control character), replace with dot
  1350. cp 07fh ;0381 Compare with DEL character (0x7F)
  1351. jr c,l0387h ;0383 If < 0x7F (printable ASCII), keep original character
  1352. l0385h:
  1353. ld (hl),02eh ;0385 Replace with '.' for non-printable characters (0x00-0x1F, 0x7F-0xFF)
  1354. l0387h:
  1355. inc hl ;0387 Move to next ASCII display position
  1356. ld (hl),02ah ;0388 Put '*' separator after ASCII character
  1357. exx ;038a Switch back to memory address registers
  1358. call sub_06c6h ;038b Display the hex value of current byte (XX format)
  1359. cpi ;038e Compare and increment HL, decrement BC (built-in loop control)
  1360. exx ;0390 Switch to buffer registers for ASCII area management
  1361. inc hl ;0391 Move buffer pointer to next ASCII position
  1362. jp po,l0727h ;0392 If BC=0 (parity odd=end of block), finish and display line
  1363. djnz l039ch ;0395 Decrement line counter B, if not 0 continue current line
  1364. call l0727h ;0397 Display the completed line (16 bytes hex + ASCII representation)
  1365. jr l035eh ;039a Start next line (display next address block)
  1366. l039ch: ; Continue current line processing
  1367. dec hl ;039c Back up buffer pointer (adjust for proper spacing)
  1368. exx ;039d Switch back to memory address registers
  1369. jr l037ah ;039e Continue byte processing loop for same line
  1370. ; =============================================================================
  1371. ; MEMORY EXAMINE AND MODIFY COMMAND (M command)
  1372. ; =============================================================================
  1373. ; Purpose: Interactive memory editing - display address, show current value,
  1374. ; allow user to enter new value, store it, and continue to next address
  1375. ; Input: HL = starting memory address (parsed from user command like "M 1000")
  1376. ; Operation: Shows "ADDR: XX" format, waits for user input, stores new value
  1377. ; User Interface: Enter new hex value to change, press Enter to skip, 'Q' to quit
  1378. ; Exit: User presses 'Q' to quit and return to monitor prompt
  1379. ; Example: "1000: 42" - shows address 1000 has value 42, user can change it
  1380. ; =============================================================================
  1381. l03a0h: ; Memory Examine/Modify Entry Point
  1382. push hl ;03a0 Save current memory address on stack
  1383. call sub_06b8h ;03a1 Display address in 4-digit hex format (e.g., "1000:")
  1384. ld a,(hl) ;03a4 Load current byte value from memory at address
  1385. call sub_0708h ;03a5 Display current value and get user input (hex parser)
  1386. jr z,l03b0h ;03a8 If no input/Enter pressed, skip to next address
  1387. pop hl ;03aa Restore memory address from stack
  1388. ld (hl),a ;03ab Store new value entered by user into memory
  1389. push hl ;03ac Save address on stack again for next iteration
  1390. call sub_0662h ;03ad Call verification/display routine (confirm change)
  1391. l03b0h: ; Next address processing
  1392. pop hl ;03b0 Restore current address from stack
  1393. cp 051h ;03b1 Compare input with 'Q' (0x51 = ASCII 'Q' for quit)
  1394. ret z ;03b3 Return to monitor prompt if user pressed 'Q'
  1395. inc hl ;03b4 Move to next memory address (auto-increment)
  1396. jr l03a0h ;03b5 Loop back to examine next byte (continue editing)
  1397. ; =============================================================================
  1398. ; MEMORY FILL COMMAND (F command) - Fill Memory Block with Pattern Byte
  1399. ; =============================================================================
  1400. ; Purpose: Fill a memory region with a specified byte value using efficient block copy
  1401. ; Input: User enters "F START END VALUE" - three hex parameters on command line
  1402. ; Operation: Fills memory from START to END (inclusive) with VALUE byte
  1403. ; Example: "F 1000 10FF 42" fills addresses 1000-10FF with 0x42 (256 bytes)
  1404. ; Special case: "FO" prefix jumps to different command handler (File Operations?)
  1405. ; Technique: Uses single byte + LDIR for efficient bulk memory fill
  1406. ; =============================================================================
  1407. l03b7h: ; Memory Fill Command Entry Point
  1408. call sub_065eh ;03b7 Get next command character from input buffer (after 'F')
  1409. cp 04fh ;03ba Compare with 'O' (0x4F = ASCII 'O')
  1410. jp z,l0a74h ;03bc If 'O', jump to File Operations handler (FO command)
  1411. call sub_0760h ;03bf Parse three hex parameters: start addr→DE, end addr→HL, value→A
  1412. and a ;03c2 Clear carry flag for subtraction (prepare SBC calculation)
  1413. ld (de),a ;03c3 Store fill value at start address (seeds the pattern)
  1414. sbc hl,de ;03c4 Calculate length = end address - start address
  1415. ret z ;03c6 Return if length is zero (start=end, only one byte filled)
  1416. ld b,h ;03c7 Move length to BC register pair (16-bit byte count)
  1417. ld c,l ;03c8 BC = number of bytes remaining to fill
  1418. ld h,d ;03c9 HL = start address (source for propagating pattern)
  1419. ld l,e ;03ca Copy DE (start) to HL
  1420. inc de ;03cb DE = start address + 1 (destination for pattern copy)
  1421. ldir ;03cc Fill memory: copy (HL) to (DE), repeat BC times
  1422. ret ;03ce Return to monitor (entire memory region now filled)
  1423. ; =============================================================================
  1424. ; DEBUG/DISPLAY PARAMETER COMMAND (I command) - Configure Display Settings
  1425. ; =============================================================================
  1426. ; Purpose: Configure debugging display parameters, modes, or formatting options
  1427. ; Input: User enters "I XXXX" where XXXX is hex value for display parameter
  1428. ; Storage: Parameter value stored at memory address 0x11D6
  1429. ; Special case: "II" command jumps to specialized display handler at 0x0A86
  1430. ; Use cases: Sets display width, format modes, or debugging visualization options
  1431. ; Examples: "I 10" might set 16-byte display width, "I 01" might enable trace mode
  1432. ; =============================================================================
  1433. l03cfh: ; I Command (Debug/Display Parameter) Entry Point
  1434. call sub_065eh ;03cf Get next command character from input buffer (check for "II")
  1435. cp 044h ;03d2 Compare with 'I' (0x49 = ASCII 'I' for "II" command variant)
  1436. jp z,l0a86h ;03d4 If second 'I', jump to specialized display command handler
  1437. ld a,(011d6h) ;03d7 Load current debug display parameter from memory (0x11D6)
  1438. call sub_0708h ;03da Get hex input from user (new parameter value for I command)
  1439. ret z ;03dd Return if no input provided (display current parameter value)
  1440. ld (011d6h),a ;03de Store new debug display parameter at 0x11D6
  1441. ret ;03e1 Return to monitor (I command parameter updated)
  1442. ; =============================================================================
  1443. ; BREAKPOINT/EXECUTION COUNTER COMMAND - Program Execution Control
  1444. ; =============================================================================
  1445. ; Purpose: Set up execution counter for controlled program stepping/tracing
  1446. ; Input: User enters hex counter value (number of instructions to execute)
  1447. ; Operation: Sets up debugging counter for single-step or limited execution
  1448. ; Use case: "B 100" might execute 256 instructions then break back to monitor
  1449. ; =============================================================================
  1450. l03e2h: ; Breakpoint/Counter Command Entry Point
  1451. call sub_03f7h ;03e2 Call setup/initialization routine (clear counters?)
  1452. call sub_0680h ;03e5 Parse hex input from user (execution count)
  1453. ret z ;03e8 Return if no valid input provided (show current count?)
  1454. call sub_0405h ;03e9 Process the counter value (setup execution limit)
  1455. sub_03ech: ; Counter Processing Subroutine - EXECUTION STEP COUNTER
  1456. call sub_0680h ;03ec Parse hex input from user (step count parameter)
  1457. jr nz,l03f3h ;03ef If valid hex input provided, store it as step count
  1458. ld a,001h ;03f1 Default step count = 1 (single step if no input)
  1459. l03f3h:
  1460. ld (011d0h),a ;03f3 Store step counter at 0x11D0 (execution step limit)
  1461. ret ;03f6 Return to single-step execution controller
  1462. ; =============================================================================
  1463. ; BREAKPOINT RESTORATION ROUTINE
  1464. ; =============================================================================
  1465. ; Purpose: Restore original instruction that was replaced by breakpoint
  1466. ; Operation: Reads saved instruction byte and restores it to memory
  1467. ; Used by: Breakpoint system to clean up after break execution
  1468. ; =============================================================================
  1469. sub_03f7h: ; Breakpoint Restoration
  1470. ld hl,(011f0h) ;03f7 Load breakpoint address from memory
  1471. ld a,(011cfh) ;03fa Load saved original instruction byte
  1472. ld (hl),a ;03fd Restore original instruction at breakpoint
  1473. ld hl,l0000h ;03fe Clear breakpoint address (set to 0000)
  1474. ld (011f0h),hl ;0401 Store cleared address (no active breakpoint)
  1475. l0404h:
  1476. ret ;0404 Return
  1477. ; =============================================================================
  1478. ; BREAKPOINT INSTALLATION ROUTINE
  1479. ; =============================================================================
  1480. ; Purpose: Install breakpoint by replacing instruction with 0xFF
  1481. ; Operation: Saves original instruction and replaces it with break opcode
  1482. ; Input: HL = address where breakpoint should be set
  1483. ; Memory: 011cfh = saved original instruction, 011f0h = breakpoint address
  1484. ; =============================================================================
  1485. sub_0405h: ; Breakpoint Installation
  1486. ld a,(hl) ;0405 Load original instruction from target address
  1487. ld (011cfh),a ;0406 Save original instruction byte
  1488. ld (hl),0ffh ;0409 Replace with breakpoint opcode (0xFF = RST 38H)
  1489. ld (011f0h),hl ;040b Store breakpoint address for later restoration
  1490. ret ;040e Return
  1491. ; =============================================================================
  1492. ; INSTRUCTION ANALYSIS AND BREAKPOINT PLACEMENT
  1493. ; =============================================================================
  1494. ; Purpose: Analyze instruction stream and set appropriate breakpoints
  1495. ; Used by: Single-step debugging and program flow analysis
  1496. ; =============================================================================
  1497. l040fh: ; Instruction Analysis Entry Point
  1498. call sub_03f7h ;040f Restore any existing breakpoint first
  1499. ld hl,(011eah) ;0412 Load current execution address
  1500. call sub_0425h ;0415 Analyze instruction at current address
  1501. jp nc,l049fh ;0418 If NOT special instruction, jump to normal execution path
  1502. ld e,a ;041b Move instruction length to E register
  1503. ld d,000h ;041c Clear D register (DE = instruction length in bytes)
  1504. add hl,de ;041e Calculate next instruction address (current + length)
  1505. call sub_0405h ;041f Set breakpoint at NEXT instruction (step-over mode)
  1506. jp l044ah ;0422 Jump to execution setup and run until breakpoint hit
  1507. ; =============================================================================
  1508. ; Z80 INSTRUCTION DECODER - Analyzes instruction types for debugging
  1509. ; =============================================================================
  1510. ; Purpose: Decode Z80 instructions to determine their type and length
  1511. ; Input: HL points to instruction to analyze
  1512. ; Output: Carry set if special instruction, A = instruction length
  1513. ; Special instructions: CALL, RET, conditional jumps, block operations
  1514. ; =============================================================================
  1515. sub_0425h: ; Z80 Instruction Decoder
  1516. ld a,(hl) ;0425 Load instruction opcode
  1517. cp 0edh ;0426 Check for ED prefix (extended instructions)
  1518. jr z,l0437h ;0428 If ED prefix, handle extended instructions
  1519. cp 0cdh ;042a Check for CALL instruction (0xCD)
  1520. jr z,l0433h ;042c If CALL, return length 3
  1521. and 0c4h ;042e Mask bits to check instruction pattern
  1522. xor 0c4h ;0430 Check for conditional CALL pattern (11xxx100)
  1523. ret nz ;0432 Return if not special instruction (carry clear)
  1524. l0433h: ; CALL instruction handler
  1525. ld a,003h ;0433 CALL instructions are 3 bytes long
  1526. scf ;0435 Set carry flag (special instruction detected)
  1527. ret ;0436 Return with instruction length
  1528. l0437h: ; Extended instruction handler (ED prefix)
  1529. inc hl ;0437 Move to second byte of ED instruction
  1530. ld a,(hl) ;0438 Load second opcode byte
  1531. and 0f0h ;0439 Mask upper nibble
  1532. xor 0b0h ;043b Check for block operation pattern (10110xxx)
  1533. ret nz ;043d Return if not block operation
  1534. inc a ;043e A = 1 (ED block instructions are 2 bytes)
  1535. scf ;043f Set carry flag (special instruction detected)
  1536. ret ;0440 Return with instruction length
  1537. ; =============================================================================
  1538. ; JUMP/EXECUTE COMMAND (J command) - Execute program from specified address
  1539. ; =============================================================================
  1540. ; Purpose: Start program execution from user-specified address (same as G command)
  1541. ; Input: User provides "J XXXX" where XXXX is hex address to execute
  1542. ; Operation: Sets up execution environment and transfers control to user program
  1543. ; Note: J command shares the same implementation as G (Go) command
  1544. ; =============================================================================
  1545. l0441h: ; J Command (Jump/Execute) Entry Point
  1546. call sub_0680h ;0441 Parse hex address from user input (e.g., "J 1000")
  1547. jp z,l02d9h ;0444 Jump to error handler if invalid address entered
  1548. ld (011eah),hl ;0447 Store execution start address in system variable
  1549. ; =============================================================================
  1550. ; PROGRAM EXECUTION CONTROLLER (shared by G and J commands)
  1551. ; =============================================================================
  1552. ; Purpose: Set up CPU state and execute user program with debugging support
  1553. ; Features: Interrupt handling, breakpoint detection, register restoration
  1554. ; Used by: Both G (Go) and J (Jump) commands use this same execution logic
  1555. ; =============================================================================
  1556. l044ah: ; Program Execution Setup
  1557. ld a,(011d7h) ;044a Load interrupt vector high byte from system config
  1558. ld i,a ;044d Set Z80 interrupt vector register (for IM2 mode)
  1559. ld de,(011eah) ;044f Load target execution address from user input (G/J command)
  1560. ld hl,(011f0h) ;0453 Load current breakpoint address from active breakpoint
  1561. and a ;0456 Clear carry flag for 16-bit address comparison
  1562. sbc hl,de ;0457 Compare: is breakpoint already at execution start address?
  1563. jr z,l0472h ;0459 If breakpoint at execution address, handle as special case
  1564. ld hl,(011d6h) ;045b Load debug control parameters (interrupt/trace modes)
  1565. ld a,h ;045e Get high byte of debug params for interrupt vector
  1566. ld i,a ;045f Set interrupt vector register for user program context
  1567. di ;0461 Disable interrupts during critical register setup phase
  1568. bit 0,l ;0462 Check debug control bit 0 (interrupt enable flag for user)
  1569. jr z,l0467h ;0464 If bit 0 clear, keep interrupts disabled during execution
  1570. ei ;0466 Re-enable interrupts if user program expects them enabled
  1571. ;==============================================================================
  1572. ; USER PROGRAM EXECUTION CONTROLLER (0x0467-0x0471)
  1573. ;==============================================================================
  1574. ; Purpose: Execute user program with full debugger support and state management
  1575. ; Entry: l0467h - Called after breakpoint setup or direct execution request
  1576. ; Operation: Restore registers → Execute user code → Handle return → Process results
  1577. ;==============================================================================
  1578. l0467h: ; Execute User Program Entry Point
  1579. call sub_079bh ;0467 CRITICAL: Restore all registers and execute user code
  1580. ld hl,(011eah) ;046a Reload execution address from save area (post-execution)
  1581. push hl ;046d Save execution address on stack for debug analysis
  1582. ld hl,(011d4h) ;046e Load debug parameters/status from execution control
  1583. ret ;0471 Return to calling debugger routine with status
  1584. ;==============================================================================
  1585. ; ERROR HANDLER AND MEMORY RESTORATION (0x0472-0x0478)
  1586. ;==============================================================================
  1587. ; Purpose: Handle execution errors and restore memory state after breakpoints
  1588. ; Used by: Debugger cleanup routines and breakpoint removal system
  1589. ;==============================================================================
  1590. l0472h: ; Error Handler Entry Point
  1591. ld hl,l07efh ;0472 Load address for execution/error handler routine
  1592. l0475h: ; Memory restoration entry point (breakpoint cleanup)
  1593. ld a,(011cfh) ;0475 Load saved byte value from backup storage location
  1594. ld (de),a ;0478 Restore original byte at target address (remove breakpoint)
  1595. ;==============================================================================
  1596. ; BREAKPOINT INSTALLATION WITH MEMORY PAGING (0x0479-0x049D)
  1597. ;==============================================================================
  1598. ; Purpose: Install software breakpoint in paged memory with full state management
  1599. ; Features: Memory paging control, interrupt management, state backup/restoration
  1600. ; Operation: Enables paging → Selects memory page → Plants breakpoint → Saves state
  1601. ;
  1602. ; Memory Paging Sequence:
  1603. ; 1. Disable interrupts for atomic operation
  1604. ; 2. Configure interrupt mode 2 with vector table at 0x1300
  1605. ; 3. Enable 64KB memory card paging system via port 0x000
  1606. ; 4. Select target memory page via dual-write to port 0x003
  1607. ; 5. Install breakpoint instruction and backup original data
  1608. ;
  1609. ; Port Operations:
  1610. ; • PORT 0x000 (0x20): Memory management control - enables bank switching
  1611. ; • PORT 0x003 (0x87, 0x01): Page selection - first 0x87 (page 7 + control), then 0x01 (page 1)
  1612. ;
  1613. ; State Management:
  1614. ; • Backs up original instruction before planting 0xFB (EI) breakpoint
  1615. ; • Stores breakpoint location and original data for safe restoration
  1616. ; • Integrates with debugger's execution control and single-step system
  1617. ;==============================================================================
  1618. l0479h: ; Breakpoint Installation Entry Point
  1619. dec de ;0479 Decrement target address by 1 (align to exact breakpoint location)
  1620. di ;047a Disable interrupts for atomic breakpoint installation
  1621. ld a,013h ;047b Set interrupt vector base 0x13 (points to table at 0x1300)
  1622. ld i,a ;047d Load interrupt vector register (prepare for IM2 mode)
  1623. ld a,020h ;047f Memory control: 0x20 = Enable 64KB paging system
  1624. out (000h),a ;0481 PORT 0x000: Memory management control (activate paging)
  1625. im 2 ;0483 Set interrupt mode 2 (vectored interrupts via table)
  1626. ld a,087h ;0485 Page select: 0x87 = Page 7 + control bits active
  1627. out (003h),a ;0487 PORT 0x003: Page selection register (first selection)
  1628. ld a,001h ;0489 Page select: 0x01 = Select memory page 1 for breakpoint
  1629. out (003h),a ;048b PORT 0x003: Page selection register (second selection)
  1630. ld (01326h),hl ;048d Store HL at 0x1326 (breakpoint address for paging system)
  1631. ex de,hl ;0490 Exchange: HL=decremented target addr, DE=original addr
  1632. ld (011d1h),hl ;0491 Store active breakpoint address at 0x11D1 (current BP)
  1633. ld a,(hl) ;0494 Load original instruction byte from breakpoint location
  1634. ld (011d3h),a ;0495 Store original byte at 0x11D3 (backup for restoration)
  1635. ld (hl),0fbh ;0498 Plant breakpoint: 0xFB = EI instruction (interrupt enable)
  1636. ld (011eah),hl ;049a Store breakpoint address at 0x11EA (execution target)
  1637. jr l0467h ;049d Jump to execution preparation (complete breakpoint cycle)
  1638. ;==============================================================================
  1639. ; NORMAL INSTRUCTION EXECUTION PATH (0x049F) - NON-SPECIAL INSTRUCTIONS
  1640. ;==============================================================================
  1641. ; Purpose: Handle execution of normal instructions (not CALL/RET/conditional jumps)
  1642. ; Entry: Jumped to from 0x0418 when instruction decoder finds standard instruction
  1643. ; Operation: Set up single-step debugging environment for normal instruction execution
  1644. ; Features: Console buffer setup, memory management, step-by-step execution control
  1645. ;==============================================================================
  1646. l049fh: ; Normal Instruction Execution Entry Point
  1647. call sub_05a5h ;049f Initialize console buffer system (prepare for single-step I/O)
  1648. call sub_03ech ;04a2 Process execution counter/step parameters
  1649. l04a5h: ; Single-Step Execution Loop Controller
  1650. ld hl,(011d6h) ;04a5 Load debug control parameters from system settings
  1651. ld (011eeh),hl ;04a8 Save debug parameters for restoration after execution
  1652. ld de,(011eah) ;04ab Load current execution address (where to execute next)
  1653. ld hl,(011f0h) ;04af Load active breakpoint address from system
  1654. and a ;04b2 Clear carry flag for 16-bit address comparison
  1655. sbc hl,de ;04b3 Compare: is execution address same as breakpoint address?
  1656. ld hl,l04bch ;04b5 Load address of breakpoint handler routine
  1657. jr z,l0475h ;04b8 If at breakpoint, jump to memory restoration routine
  1658. jr l0479h ;04ba Otherwise, jump to breakpoint installation routine
  1659. l04bch:
  1660. ld (011d4h),hl ;04bc Store execution return address in debug control block
  1661. pop hl ;04bf Restore HL register from stack (return to caller state)
  1662. ld (011ech),sp ;04c0 Save current stack pointer for later restoration
  1663. ld sp,01400h ;04c4 Set up temporary debug stack at 0x1400
  1664. call sub_0770h ;04c7 Call system state preservation routine
  1665. call sub_04ebh ;04ca Call memory paging restore routine
  1666. ld hl,l04d3h ;04cd Load address of execution continuation point
  1667. push hl ;04d0 Push continuation address onto stack
  1668. reti ;04d1 Return from interrupt (execute user instruction)
  1669. l04d3h:
  1670. ld hl,(011eeh) ;04d3 Restore debug control parameters from backup
  1671. ld (011d6h),hl ;04d6 Store restored parameters back to system settings
  1672. call sub_0582h ;04d9 Call post-execution cleanup routine
  1673. ld hl,011d0h ;04dc Point to single-step counter location
  1674. dec (hl) ;04df Decrement step counter (one instruction executed)
  1675. jr nz,l04a5h ;04e0 If more steps remaining, continue execution loop
  1676. inc (hl) ;04e2 Reset step counter to 1 (prepare for next command)
  1677. call sub_080dh ;04e3 Call debugger command processing routine
  1678. jp nz,l02c9h ;04e6 If command processed, jump to main command loop
  1679. jr l04a5h ;04e9 Otherwise, continue single-step execution
  1680. ;==============================================================================
  1681. ; MEMORY PAGING RESTORE ROUTINE (0x04EB)
  1682. ;==============================================================================
  1683. ; Purpose: Restore default memory page and clean up paging state
  1684. ; Called during system shutdown or page switching operations
  1685. ;
  1686. ; Operation:
  1687. ; - Switches back to page 3 (likely default/system page)
  1688. ; - Restores original memory contents from backup
  1689. ; - Cleans up paging state for safe transition
  1690. ;==============================================================================
  1691. sub_04ebh:
  1692. ld a,003h ;04eb ; Load page 3 (default/system page)
  1693. out (003h),a ;04ed ; PORT 0x003: Switch to page 3
  1694. ld hl,(011d1h) ;04ef ; Load backup memory address
  1695. ld a,(011d3h) ;04f2 ; Load original byte value
  1696. ld (hl),a ;04f5 ; Restore original memory contents
  1697. ld hl,(011f0h) ;04f6 ; Load cleanup address
  1698. ld (hl),0ffh ;04f9 ; Mark memory as restored/available
  1699. ret ;04fb ; Return to caller
  1700. call sub_0760h ;04fc
  1701. jp z,l02d9h ;04ff
  1702. push hl ;0502
  1703. and a ;0503
  1704. sbc hl,de ;0504
  1705. pop hl ;0506
  1706. l0507h:
  1707. jr c,l050ch ;0507
  1708. l0509h:
  1709. ldir ;0509
  1710. ret ;050b
  1711. l050ch:
  1712. add hl,bc ;050c
  1713. dec hl ;050d
  1714. ex de,hl ;050e
  1715. add hl,bc ;050f
  1716. dec hl ;0510
  1717. ex de,hl ;0511
  1718. lddr ;0512
  1719. ret ;0514
  1720. call sub_0662h ;0515
  1721. jr z,l057fh ;0518
  1722. ld d,a ;051a
  1723. call sub_065eh ;051b
  1724. jr nz,l0522h ;051e
  1725. ld a,020h ;0520
  1726. l0522h:
  1727. ld e,a ;0522
  1728. call sub_05cch ;0523
  1729. dec hl ;0526
  1730. dec hl ;0527
  1731. jp nz,l02d9h ;0528
  1732. l052bh:
  1733. ld de,01104h ;052b
  1734. ldi ;052e
  1735. ldi ;0530
  1736. push hl ;0532
  1737. ex de,hl ;0533
  1738. ld (hl),020h ;0534
  1739. inc hl ;0536
  1740. ld (011f2h),hl ;0537
  1741. ld hl,l060eh ;053a
  1742. or a ;053d
  1743. ex de,hl ;053e
  1744. sbc hl,de ;053f
  1745. ld e,(ix+000h) ;0541
  1746. ld d,(ix+001h) ;0544
  1747. jr nc,l056ah ;0547
  1748. ld a,(de) ;0549
  1749. push de ;054a
  1750. call sub_0708h ;054b
  1751. pop de ;054e
  1752. jr z,l0555h ;054f
  1753. ld (de),a ;0551
  1754. l0552h:
  1755. call sub_0662h ;0552
  1756. l0555h:
  1757. cp 051h ;0555
  1758. pop hl ;0557
  1759. ret z ;0558
  1760. inc ix ;0559
  1761. inc ix ;055b
  1762. ex de,hl ;055d
  1763. push hl ;055e
  1764. ld hl,l0615h ;055f
  1765. or a ;0562
  1766. sbc hl,de ;0563
  1767. pop hl ;0565
  1768. ex de,hl ;0566
  1769. jr nz,l052bh ;0567
  1770. ret ;0569
  1771. l056ah:
  1772. ld a,(de) ;056a
  1773. ld l,a ;056b
  1774. inc de ;056c
  1775. ld a,(de) ;056d
  1776. ld h,a ;056e
  1777. call sub_06b8h ;056f
  1778. push de ;0572
  1779. call sub_070bh ;0573
  1780. pop de ;0576
  1781. jr z,l0555h ;0577
  1782. ex de,hl ;0579
  1783. ld (hl),d ;057a
  1784. dec hl ;057b
  1785. ld (hl),e ;057c
  1786. jr l0552h ;057d
  1787. l057fh:
  1788. call sub_05a5h ;057f
  1789. sub_0582h:
  1790. ld b,011h ;0582
  1791. ld hl,l0615h ;0584
  1792. l0587h:
  1793. ld e,(hl) ;0587
  1794. inc hl ;0588
  1795. ld d,(hl) ;0589
  1796. inc hl ;058a
  1797. ld a,(de) ;058b
  1798. call sub_06c6h ;058c
  1799. djnz l0587h ;058f
  1800. ld b,004h ;0591
  1801. l0593h:
  1802. ld e,(hl) ;0593
  1803. inc hl ;0594
  1804. ld d,(hl) ;0595
  1805. inc hl ;0596
  1806. ex de,hl ;0597
  1807. ld a,(hl) ;0598
  1808. inc hl ;0599
  1809. ld h,(hl) ;059a
  1810. ld l,a ;059b
  1811. call sub_06b8h ;059c
  1812. ex de,hl ;059f
  1813. djnz l0593h ;05a0
  1814. l05a2h:
  1815. jp sub_072ah ;05a2
  1816. ;==============================================================================
  1817. ; CONSOLE BUFFER INITIALIZATION (sub_05a5h) - REGISTER DISPLAY SETUP
  1818. ;==============================================================================
  1819. ; Purpose: Initialize console buffer system with register name templates
  1820. ; Operation: Copy register name strings from ROM table to RAM buffer area
  1821. ; Used by: Single-step debugging to prepare register display output
  1822. ; Buffer: 0x1104 = console buffer start, filled with register names for display
  1823. ;==============================================================================
  1824. sub_05a5h: ; Console Buffer Initialization Entry Point
  1825. ld de,01104h ;05a5 DE = console buffer start address (0x1104)
  1826. ld hl,l05ebh ;05a8 HL = register name table in ROM (0x05EB - register names)
  1827. ld bc,011ffh ;05ab BC = loop count (B=0x01, C=0xFF - copy parameters)
  1828. ld a,020h ;05ae A = 0x20 (space character for formatting)
  1829. l05b0h: ; Register Name Copy Loop
  1830. ldi ;05b0 Copy first character from register table to buffer
  1831. ldi ;05b2 Copy second character from register table to buffer
  1832. ld (de),a ;05b4 Store space character (0x20) after register name
  1833. inc de ;05b5 Advance buffer pointer past space
  1834. djnz l05b0h ;05b6 Loop until all register names copied (B times)
  1835. ld b,004h ;05b8 Set loop counter for additional buffer setup (4 iterations)
  1836. l05bah: ; Additional Buffer Formatting Loop
  1837. ld (de),a ;05ba Store space character in buffer
  1838. inc de ;05bb Advance buffer pointer
  1839. ldi ;05bc Copy character from register table to buffer
  1840. ldi ;05be Copy second character from register table to buffer
  1841. ld (de),a ;05c0 Store space character after register name
  1842. inc de ;05c1 Advance buffer pointer
  1843. ld (de),a ;05c2 Store another space character (double spacing)
  1844. inc de ;05c3 Advance buffer pointer
  1845. djnz l05bah ;05c4 Loop for remaining register names (4 times)
  1846. ld (011f2h),de ;05c6 Store final buffer pointer at 0x11F2 (buffer end)
  1847. jr l05a2h ;05ca Jump to buffer completion routine
  1848. sub_05cch:
  1849. ld ix,l0615h ;05cc
  1850. ld bc,l002ah ;05d0
  1851. ld hl,l05ebh ;05d3
  1852. l05d6h:
  1853. ld a,d ;05d6
  1854. cpi ;05d7
  1855. jr z,l05e5h ;05d9
  1856. xor a ;05db
  1857. cpi ;05dc
  1858. l05deh:
  1859. ret po ;05de
  1860. inc ix ;05df
  1861. inc ix ;05e1
  1862. jr l05d6h ;05e3
  1863. l05e5h:
  1864. ld a,e ;05e5
  1865. cpi ;05e6
  1866. ret z ;05e8
  1867. jr l05deh ;05e9
  1868. ;==============================================================================
  1869. ; Z80 REGISTER NAME TABLE (0x05EB+)
  1870. ; Purpose: ASCII string table of Z80 register names for display/debugging
  1871. ; Format: Space-separated register names, single quotes for alternate registers
  1872. ; Content: "A B C D E F H L I A'B'C'D'E'F'H'L'IXI..."
  1873. ;==============================================================================
  1874. ;==============================================================================
  1875. ; Z80 REGISTER NAME AND ADDRESS LOOKUP TABLE (0x05EB-0x63D)
  1876. ; Purpose: Complete register name table with corresponding addresses for debugger/monitor
  1877. ; Format: ASCII register names followed by address lookup table
  1878. ;==============================================================================
  1879. register_names_05ebh:
  1880. ; Register name strings (space-separated)
  1881. db "A B C D E F H L I A'B'C'D'E'F'H'L'IXI" ;05eb-060f
  1882. db "YPCSP" ;0610-0614 (IY, PC, SP registers)
  1883. ; Address lookup table (each entry is 0x11 followed by address)
  1884. db 0xD9, 0x11, 0xDB, 0x11, 0xDA, 0x11, 0xDD, 0x11 ;0615-061c
  1885. db 0xDC, 0x11, 0xD8, 0x11, 0xD5, 0x11, 0xD4, 0x11 ;061d-0624
  1886. db 0xD7, 0x11, 0xDF, 0x11, 0xE1, 0x11, 0xE0, 0x11 ;0625-062c
  1887. db 0xE3, 0x11, 0xE2, 0x11, 0xDE, 0x11, 0xE5, 0x11 ;062d-0634
  1888. db 0xE4, 0x11, 0xE6, 0x11, 0xE8, 0x11, 0xEA, 0x11 ;0635-063c
  1889. db 0xEC, 0x11 ;063d-063e
  1890. ;==============================================================================
  1891. ; HEX INPUT SEQUENCE (0x063F)
  1892. ;==============================================================================
  1893. ; Purpose: Parse two hexadecimal values from user input
  1894. ; Typical use: Address and data entry for memory operations
  1895. ; Example: User types "1000 FF" to store 0xFF at address 0x1000
  1896. ;==============================================================================
  1897. sub_063fh:
  1898. call sub_0680h ;063f ; Parse first hex string (e.g., address)
  1899. push hl ;0642 ; Save first parsed value on stack
  1900. call sub_0680h ;0643 ; Parse second hex string (e.g., data)
  1901. pop hl ;0646 ; Restore first value to HL
  1902. ret z ;0647 ; Return if second parse failed
  1903. ld (hl),a ;0648 ; Store second value (data) at first value (address)
  1904. inc hl ;0649 ; Increment to next address
  1905. jr $-8 ;064a ; Loop back to continue operation
  1906. sub_064ch:
  1907. ex (sp),hl ;064c
  1908. ld b,(hl) ;064d
  1909. l064eh:
  1910. inc hl ;064e
  1911. cp (hl) ;064f
  1912. inc hl ;0650
  1913. ld e,(hl) ;0651
  1914. inc hl ;0652
  1915. ld d,(hl) ;0653
  1916. jr nz,l0659h ;0654
  1917. ex de,hl ;0656
  1918. ex (sp),hl ;0657
  1919. ret ;0658
  1920. l0659h:
  1921. djnz l064eh ;0659
  1922. jp l02d9h ;065b
  1923. sub_065eh:
  1924. inc hl ;065e
  1925. ld a,(hl) ;065f
  1926. jr l0677h ;0660
  1927. ; =============================================================================
  1928. ; INPUT BUFFER SCANNER - Skip Spaces and Process Next Character
  1929. ; =============================================================================
  1930. ; Purpose: Scan input buffer, skip spaces, and return next non-space character
  1931. ; Input: (011f4h) points to current position in input buffer
  1932. ; Output: A = next non-space character, HL updated to new position
  1933. ; Used by: Memory modify command to parse user input after displaying value
  1934. ; =============================================================================
  1935. sub_0662h: ; Input Buffer Scanner
  1936. ld hl,(011f4h) ;0662 Load current input buffer pointer
  1937. l0665h: ; Space-skipping loop
  1938. ld a,(hl) ;0665 Load character from buffer
  1939. cp 00dh ;0666 Check for CR (end of line)
  1940. jr z,l0674h ;0668 If CR, finish and update pointer
  1941. cp 020h ;066a Check for space character
  1942. l066ch: ; Continue scanning loop
  1943. inc hl ;066c Move to next character
  1944. jr nz,l0665h ;066d If not space, check if still space at new position
  1945. ld a,(hl) ;066f Load next character
  1946. cp 020h ;0670 Check if it's also a space
  1947. jr z,l066ch ;0672 If space, continue skipping spaces
  1948. l0674h: ; Update buffer pointer and process character
  1949. ld (011f4h),hl ;0674 Store updated buffer pointer
  1950. l0677h: ; Character processing
  1951. bit 6,a ;0677 Check bit 6 (lowercase letter detection)
  1952. jr z,l067dh ;0679 If not set, skip case conversion
  1953. res 5,a ;067b Convert lowercase to uppercase (clear bit 5)
  1954. l067dh: ; Final character check
  1955. cp 00dh ;067d Compare with CR (carriage return)
  1956. ret ;067f Return with flags set
  1957. ;==============================================================================
  1958. ; HEXADECIMAL STRING PARSER (0x0680)
  1959. ;==============================================================================
  1960. ; Purpose: Convert ASCII hexadecimal string to binary value
  1961. ; Input: DE points to ASCII hex string (e.g. "1A2F")
  1962. ; Output: HL contains parsed binary value, A contains last character processed
  1963. ;
  1964. ; Supported formats:
  1965. ; - Digits 0-9 (ASCII 0x30-0x39)
  1966. ; - Letters A-F (ASCII 0x41-0x46, case insensitive)
  1967. ; - Automatically converts lowercase a-f to uppercase A-F
  1968. ;
  1969. ; Error handling: Invalid characters cause jump to error handler at l02d9h
  1970. ;
  1971. ; Algorithm:
  1972. ; 1. Initialize result to 0
  1973. ; 2. For each character: validate, convert, pack into result
  1974. ; 3. Use RLD instruction for efficient 4-bit nibble packing
  1975. ; 4. Continue until non-hex character found
  1976. ;==============================================================================
  1977. sub_0680h:
  1978. ld hl,l0000h ;0680 ; Initialize result to 0
  1979. push hl ;0683 ; Save initial value on stack
  1980. add hl,sp ;0684 ; HL = stack pointer (for result storage)
  1981. ex de,hl ;0685 ; DE = stack pointer, HL = string pointer
  1982. call sub_0662h ;0686 ; Get next character from input
  1983. ex de,hl ;0689 ; Restore: HL = stack pointer, DE = string pointer
  1984. jr nz,l068fh ;068a ; If character available, process it
  1985. l068ch:
  1986. pop hl ;068c ; Restore result from stack
  1987. ld a,l ;068d ; Return low byte in A
  1988. ret ;068e ; Return with parsed value
  1989. l068fh:
  1990. cp 030h ;068f ; Compare with '0' (0x30)
  1991. jp c,l02d9h ;0691 ; If < '0', invalid hex character - error
  1992. l0694h:
  1993. cp 041h ;0694 ; Compare with 'A' (0x41)
  1994. jr c,l069ah ;0696 ; If < 'A', must be digit 0-9, go convert
  1995. res 5,a ;0698 ; Convert lowercase to uppercase (clear bit 5)
  1996. l069ah:
  1997. cp 03ah ;069a ; Compare with ':' (0x3A, one past '9')
  1998. jr c,l06aah ;069c ; If < ':', it's digit 0-9, go pack
  1999. cp 041h ;069e ; Compare with 'A' (0x41)
  2000. jp c,l02d9h ;06a0 ; If between ':' and 'A', invalid - error
  2001. cp 047h ;06a3 ; Compare with 'G' (0x47, one past 'F')
  2002. jp nc,l02d9h ;06a5 ; If >= 'G', invalid hex letter - error
  2003. sub 007h ;06a8 ; Convert A-F to 10-15 (subtract 7)
  2004. l06aah:
  2005. rld ;06aa ; Rotate left digit: pack nibble into (HL)
  2006. inc hl ;06ac ; Point to next byte for multi-byte values
  2007. rld ;06ad ; Pack into high nibble of next byte
  2008. dec hl ;06af ; Return to original position
  2009. inc de ;06b0 ; Point to next character in input string
  2010. ld a,(de) ;06b1 ; Load next character
  2011. cp 030h ;06b2 ; Check if >= '0'
  2012. jr nc,l0694h ;06b4 ; If valid hex character, continue parsing
  2013. jr l068ch ;06b6 ; Otherwise, end parsing and return result
  2014. ;==============================================================================
  2015. ; 16-BIT HEX ADDRESS FORMATTER (0x06B8)
  2016. ;==============================================================================
  2017. ; Purpose: Convert 16-bit value in HL to 4-digit hex string and store in output buffer
  2018. ; Used extensively throughout the monitor for displaying memory addresses,
  2019. ; breakpoint locations, and register values in XXXX format.
  2020. ;
  2021. ; Input: HL = 16-bit value to format (e.g., memory address)
  2022. ; Output: 4-character hex string written to console buffer at (0x011F2)
  2023. ; Followed by a space character for proper formatting
  2024. ; Buffer: Updates 0x011F2 pointer to reflect new buffer position
  2025. ;
  2026. ; Format: Converts 0x1234 → "1234 " (4 hex digits + space)
  2027. ; Usage: Called by memory display, breakpoint display, register dump routines
  2028. ;
  2029. ; Technical Details:
  2030. ; • Processes high byte (H) first, then low byte (L)
  2031. ; • Each byte converted to 2 hex characters using sub_06c6h
  2032. ; • Automatically adds space separator after hex digits
  2033. ; • Updates buffer pointer for subsequent output operations
  2034. ;==============================================================================
  2035. sub_06b8h:
  2036. ld a,h ;06b8 ; Load high byte of 16-bit value
  2037. call sub_06c6h ;06b9 ; Convert high byte to 2 hex characters
  2038. push hl ;06bc ; Save original 16-bit value
  2039. ld hl,(011f2h) ;06bd ; Load current console buffer pointer
  2040. dec hl ;06c0 ; Back up one position (preparation for space)
  2041. ld (011f2h),hl ;06c1 ; Update buffer pointer
  2042. pop hl ;06c4 ; Restore original 16-bit value
  2043. ld a,l ;06c5 ; Load low byte of 16-bit value
  2044. ;==============================================================================
  2045. ; SINGLE BYTE HEX FORMATTER (0x06C6)
  2046. ;==============================================================================
  2047. ; Purpose: Convert single byte to 2-digit hex string and store in output buffer
  2048. ; Input: A = byte value to convert (0x00-0xFF)
  2049. ; Output: 2-character hex string written to buffer, followed by space
  2050. ; Used by: 16-bit formatter above, and other hex display routines
  2051. ;==============================================================================
  2052. sub_06c6h:
  2053. push hl ;06c6 ; Save registers
  2054. ld hl,(011f2h) ;06c7 ; Load current console buffer pointer
  2055. call sub_06d6h ;06ca ; Convert byte to 2 hex characters at buffer
  2056. inc hl ;06cd ; Move past the 2 hex characters
  2057. ld (hl),020h ;06ce ; Store space character (0x20) for separation
  2058. inc hl ;06d0 ; Move past space character
  2059. ld (011f2h),hl ;06d1 ; Update buffer pointer to new position
  2060. pop hl ;06d4 ; Restore registers
  2061. ret ;06d5
  2062. ;==============================================================================
  2063. ; BYTE TO HEX DIGIT CONVERTER (0x06D6)
  2064. ;==============================================================================
  2065. ; Purpose: Convert single byte to 2 ASCII hex characters
  2066. ; Input: A = byte value, HL = buffer location
  2067. ; Output: 2 hex characters stored at HL and HL+1
  2068. ; Method: Splits byte into high/low nibbles, converts each to ASCII hex
  2069. ;==============================================================================
  2070. sub_06d6h:
  2071. push af ;06d6 ; Save original byte value
  2072. rra ;06d7 ; Rotate right 4 times to get high nibble
  2073. rra ;06d8 ; in low 4 bits
  2074. rra ;06d9
  2075. rra ;06da
  2076. call sub_06e0h ;06db ; Convert high nibble to hex character
  2077. inc hl ;06de ; Move to next buffer position
  2078. pop af ;06df ; Restore original byte value
  2079. ;==============================================================================
  2080. ; NIBBLE TO HEX CHARACTER CONVERTER (0x06E0)
  2081. ;==============================================================================
  2082. ; Purpose: Convert single nibble (0-15) to ASCII hex character
  2083. ; Input: A = nibble value (0-15), HL = buffer location
  2084. ; Output: ASCII hex character ('0'-'9', 'A'-'F') stored at (HL)
  2085. ;==============================================================================
  2086. sub_06e0h:
  2087. and 00fh ;06e0 ; Mask to get only low 4 bits (nibble)
  2088. cp 00ah ;06e2 ; Compare with 10
  2089. jr c,l06e8h ;06e4 ; If < 10, convert to '0'-'9'
  2090. add a,007h ;06e6 ; If >= 10, add 7 to convert to 'A'-'F'
  2091. l06e8h:
  2092. add a,030h ;06e8 ; Add ASCII '0' offset to get final character
  2093. ld (hl),a ;06ea ; Store ASCII hex character in buffer
  2094. ret ;06eb ; Return
  2095. ;==============================================================================
  2096. ; CONSOLE OUTPUT FORMATTER & UTILITIES (0x06EC-0x076F)
  2097. ;==============================================================================
  2098. ; Collection of routines for formatting and outputting data to the console
  2099. ; with proper control characters and formatting.
  2100. ;==============================================================================
  2101. ;==============================================================================
  2102. ; STRING DISPLAY WITH CONTROL FORMATTING (0x06EC)
  2103. ;==============================================================================
  2104. ; Purpose: Display string from HL with proper control character formatting
  2105. ; Adds ETX (0x02) prefix and EOT (0x03) suffix around displayed text
  2106. ; Used for formatted console output with control framing
  2107. ;==============================================================================
  2108. l06ech:
  2109. inc hl ;06ec ; Move to start of string data
  2110. ld c,002h ;06ed ; Load ETX control character (Start of Text)
  2111. call sub_0111h ;06ef ; Send ETX to serial port
  2112. l06f2h:
  2113. ld a,(hl) ;06f2 ; Load next character from string
  2114. cp 020h ;06f3 ; Check if space character (end marker)
  2115. jr z,l0702h ;06f5 ; If space, end string output
  2116. cp 00dh ;06f7 ; Check if carriage return (end marker)
  2117. jr z,l0702h ;06f9 ; If CR, end string output
  2118. ld c,a ;06fb ; Load character into C for output
  2119. call sub_0111h ;06fc ; Send character to serial port
  2120. inc hl ;06ff ; Move to next character
  2121. jr l06f2h ;0700 ; Continue until end marker found
  2122. l0702h:
  2123. ld c,003h ;0702 ; Load EOT control character (End of Text)
  2124. call sub_0111h ;0704 ; Send EOT to serial port
  2125. ret ;0707 ; Return
  2126. ;==============================================================================
  2127. ; HEX BYTE DISPLAY WITH INPUT PROMPT (0x0708)
  2128. ;==============================================================================
  2129. ; Purpose: Display byte value and prompt for user input
  2130. ; Used by memory examination commands for interactive editing
  2131. ;==============================================================================
  2132. sub_0708h:
  2133. call sub_06c6h ;0708 ; Format and display byte as 2-digit hex + space
  2134. ;==============================================================================
  2135. ; CONSOLE OUTPUT FLUSH AND INPUT PROMPT (0x070B)
  2136. ;==============================================================================
  2137. ; Purpose: Flush current output buffer and prompt for user input
  2138. ; Sets up interactive prompt with space character and waits for input
  2139. ;==============================================================================
  2140. sub_070bh:
  2141. call sub_0745h ;070b ; Flush output buffer to console
  2142. ld a,020h ;070e ; Load space character
  2143. ld (011f6h),a ;0710 ; Set prompt character to space
  2144. call sub_080dh ;0713 ; Get character from user input
  2145. cp 051h ;0716 ; Check if 'Q' (quit command)
  2146. ret z ;0718 ; Return if user wants to quit
  2147. ld hl,01168h ;0719 ; Load input buffer address
  2148. ld (hl),020h ;071c ; Initialize buffer with space
  2149. ld (011f4h),hl ;071e ; Set input buffer pointer
  2150. push de ;0721 ; Save DE register
  2151. call sub_0680h ;0722 ; Parse hex input from user
  2152. pop de ;0725 ; Restore DE register
  2153. ret ;0726 ; Return
  2154. ;==============================================================================
  2155. ; OUTPUT BUFFER MANAGEMENT ROUTINES (0x0727-0x076F)
  2156. ;==============================================================================
  2157. ; Purpose: Handle console output buffer operations including line formatting,
  2158. ; buffer flushing, and register preservation during I/O operations
  2159. ;==============================================================================
  2160. ;==============================================================================
  2161. ; SET OUTPUT BUFFER POINTER (0x0727)
  2162. ;==============================================================================
  2163. l0727h:
  2164. ld (011f2h),hl ;0727 ; Store HL as new output buffer pointer
  2165. ;==============================================================================
  2166. ; FLUSH OUTPUT WITH NEWLINE (0x072A)
  2167. ;==============================================================================
  2168. ; Purpose: Add CR/LF to output buffer and flush to console
  2169. ; Preserves all registers during output operation
  2170. ;==============================================================================
  2171. sub_072ah:
  2172. push hl ;072a ; Save all registers
  2173. push de ;072b
  2174. push bc ;072c
  2175. ld hl,(011f2h) ;072d ; Load current buffer pointer
  2176. ld (hl),00dh ;0730 ; Add carriage return
  2177. inc hl ;0732 ; Move to next position
  2178. ld (hl),00ah ;0733 ; Add line feed
  2179. inc hl ;0735 ; Move to next position
  2180. l0736h:
  2181. ld (hl),000h ;0736 ; Add null terminator
  2182. ld hl,01104h ;0738 ; Reset buffer pointer to start
  2183. ld (011f2h),hl ;073b ; Update buffer pointer
  2184. call l00fdh ;073e ; Send buffer contents to console
  2185. pop bc ;0741 ; Restore all registers
  2186. pop de ;0742
  2187. pop hl ;0743
  2188. ret ;0744 ; Return
  2189. ;==============================================================================
  2190. ; FLUSH OUTPUT WITHOUT NEWLINE (0x0745)
  2191. ;==============================================================================
  2192. ; Purpose: Flush current output buffer to console without adding newline
  2193. ; Used for partial line output and formatting
  2194. ;==============================================================================
  2195. sub_0745h:
  2196. push hl ;0745 ; Save all registers
  2197. push de ;0746
  2198. push bc ;0747
  2199. ld hl,(011f2h) ;0748 ; Load current buffer pointer
  2200. jr l0736h ;074b ; Jump to common flush routine
  2201. ;==============================================================================
  2202. ; OUTPUT BUFFER WITH CHARACTER INPUT (0x074D)
  2203. ;==============================================================================
  2204. ; Purpose: Flush output buffer and get character input from console
  2205. ; Returns input character while preserving registers
  2206. ;==============================================================================
  2207. sub_074dh:
  2208. push hl ;074d ; Save registers
  2209. push de ;074e
  2210. ld hl,(011f2h) ;074f ; Load current buffer pointer
  2211. ld (hl),000h ;0752 ; Add null terminator
  2212. ld hl,01104h ;0754 ; Reset buffer pointer to start
  2213. ld (011f2h),hl ;0757 ; Update buffer pointer
  2214. call l0107h ;075a ; Output buffer and get input character
  2215. pop de ;075d ; Restore registers
  2216. pop hl ;075e
  2217. ret ;075f ; Return with input character in A
  2218. ;==============================================================================
  2219. ; MULTI-PARAMETER HEX INPUT PARSER (0x0760-0x076F)
  2220. ;==============================================================================
  2221. ; Purpose: Parse multiple hexadecimal parameters from user input
  2222. ; Returns parsed values in HL, DE, and BC registers
  2223. ;==============================================================================
  2224. sub_0760h:
  2225. call sub_0680h ;0760 ; Parse first hex parameter → HL
  2226. ;==============================================================================
  2227. ; TWO-PARAMETER HEX INPUT PARSER (0x0763)
  2228. ;==============================================================================
  2229. sub_0763h:
  2230. push hl ;0763 ; Save first parameter
  2231. call sub_0680h ;0764 ; Parse second hex parameter → HL
  2232. push hl ;0767 ; Save second parameter
  2233. call sub_0680h ;0768 ; Parse third hex parameter → HL
  2234. ld b,h ;076b ; Store third parameter high byte in B
  2235. ld c,l ;076c ; Store third parameter low byte in C
  2236. pop hl ;076d ; Restore second parameter to HL
  2237. pop de ;076e ; Restore first parameter to DE
  2238. ret ;076f ; Return: DE=1st param, HL=2nd param, BC=3rd param
  2239. ;==============================================================================
  2240. ; COMPLETE CPU STATE SAVE ROUTINE (sub_0770h) - CRITICAL SYSTEM COMPONENT
  2241. ;==============================================================================
  2242. ; Purpose: Save ALL Z80 CPU registers and set up interrupt environment
  2243. ; Used by: Interrupt handlers, breakpoint system, system initialization
  2244. ; Operation: Saves complete CPU state to stack area, sets up IM2 interrupts
  2245. ; Stack Layout: Creates complete register save area for later restoration
  2246. ;
  2247. ; REGISTER SAVE ORDER (pushed to stack at 0x011EC):
  2248. ; 1. HL (main register pair)
  2249. ; 2. IY (index register Y)
  2250. ; 3. IX (index register X)
  2251. ; 4. HL' (alternate HL)
  2252. ; 5. DE' (alternate DE)
  2253. ; 6. BC' (alternate BC)
  2254. ; 7. AF' (alternate accumulator/flags)
  2255. ; 8. DE (main register pair)
  2256. ; 9. BC (main register pair)
  2257. ; 10. AF (main accumulator/flags)
  2258. ; 11. I register status (interrupt vector register)
  2259. ;==============================================================================
  2260. sub_0770h: ; Complete CPU State Save Entry Point
  2261. ld sp,011ech ;0770 Set stack pointer to register save area (0x011EC)
  2262. push hl ;0773 Save main HL register pair
  2263. push iy ;0774 Save IY index register (2 bytes)
  2264. push ix ;0776 Save IX index register (2 bytes)
  2265. exx ;0778 Switch to alternate register set
  2266. push hl ;0779 Save alternate HL register pair
  2267. push de ;077a Save alternate DE register pair
  2268. push bc ;077b Save alternate BC register pair
  2269. ex af,af' ;077c Switch to alternate AF register
  2270. push af ;077d Save alternate AF (accumulator/flags)
  2271. exx ;077e Switch back to main register set
  2272. ex af,af' ;077f Switch back to main AF register
  2273. push de ;0780 Save main DE register pair
  2274. push bc ;0781 Save main BC register pair
  2275. push af ;0782 Save main AF (accumulator/flags)
  2276. ld a,i ;0783 Load interrupt vector register into A
  2277. push af ;0785 Save interrupt vector register status
  2278. ld a,(011d6h) ;0786 Load debug control parameters from system config
  2279. rra ;0789 Rotate right bit 0 (extract interrupt enable flag)
  2280. rra ;078a Rotate right bit 1 (extract trace mode flag)
  2281. and 001h ;078b Mask to keep only bit 0 (interrupt enable for user)
  2282. ld (011d6h),a ;078d Store processed debug control back to memory
  2283. ld a,013h ;0790 Load interrupt vector base 0x13 (table at 0x1300)
  2284. ld i,a ;0792 Set interrupt vector register for system operation
  2285. im 2 ;0794 Set interrupt mode 2 (vectored interrupts)
  2286. ei ;0796 Enable interrupts for system operation
  2287. ld sp,013feh ;0797 Set stack pointer to system stack area (near top of RAM)
  2288. ret ;079a Return with complete CPU state saved
  2289. ; =============================================================================
  2290. ; USER PROGRAM EXECUTION ENGINE
  2291. ; =============================================================================
  2292. ; Purpose: Restore all CPU registers and transfer control to user program
  2293. ; Operation: Complete register restoration from saved state, then execute
  2294. ; Input: Stack contains saved register state, execution address in HL
  2295. ;==============================================================================
  2296. ; USER PROGRAM EXECUTION ENGINE (sub_079bh) - CRITICAL SYSTEM COMPONENT
  2297. ;==============================================================================
  2298. ; Purpose: Complete register restoration and user program execution
  2299. ; Entry: Called from 0x0467 after breakpoint installation or direct execution
  2300. ; Operation: Restore ALL CPU state → Execute user program → Handle completion
  2301. ; Exit: User program runs with full CPU state, returns via interrupt/break
  2302. ;
  2303. ; EXECUTION FLOW:
  2304. ; 1. Breakpoint installed at target address (0x0479)
  2305. ; 2. Control transferred to execution controller (0x0467)
  2306. ; 3. Register restoration engine called (sub_079bh)
  2307. ; 4. Complete CPU state restored from memory (0x011D8)
  2308. ; 5. User program executed via jp (hl)
  2309. ; 6. Returns via interrupt handler when breakpoint hit or error occurs
  2310. ;
  2311. ; REGISTER SAVE AREA LAYOUT (0x011D8):
  2312. ; • AF (main accumulator/flags)
  2313. ; • BC (main register pair)
  2314. ; • DE (main register pair)
  2315. ; • AF' (alternate accumulator/flags)
  2316. ; • BC' (alternate register pair)
  2317. ; • DE' (alternate register pair)
  2318. ; • HL' (alternate register pair)
  2319. ; • IX (index register X)
  2320. ; • IY (index register Y)
  2321. ; • SP (user stack pointer at 0x011EC)
  2322. ;==============================================================================
  2323. sub_079bh: ; User Program Execution Engine - Heart of debugger execution
  2324. pop hl ;079b Get return address from stack (user program target address)
  2325. ld sp,011d8h ;079c Point stack pointer to register save area at 0x011D8
  2326. pop af ;079f Restore main AF (accumulator + flags) from save area
  2327. pop bc ;07a0 Restore main BC register pair from save area
  2328. pop de ;07a1 Restore main DE register pair from save area
  2329. ex af,af' ;07a2 Switch to alternate AF register (prepare for alt restore)
  2330. exx ;07a3 Switch to alternate BC,DE,HL registers (prepare for alt restore)
  2331. pop af ;07a4 Restore alternate AF register from save area
  2332. pop bc ;07a5 Restore alternate BC register from save area
  2333. pop de ;07a6 Restore alternate DE register from save area
  2334. pop hl ;07a7 Restore alternate HL register (contains execution target!)
  2335. pop ix ;07a8 Restore IX index register from save area
  2336. pop iy ;07aa Restore IY index register from save area
  2337. exx ;07ac Switch back to main register set (BC,DE,HL)
  2338. ex af,af' ;07ad Switch back to main AF register
  2339. ld sp,(011ech) ;07ae Restore user's original stack pointer from 0x011EC
  2340. jp (hl) ;07b2 EXECUTE USER PROGRAM! Jump to target in HL register
  2341. ;==============================================================================
  2342. ; INTERRUPT/ERROR HANDLER (0x07B3)
  2343. ;==============================================================================
  2344. ; Purpose: Handle interrupts or errors, display "BREAK AT " message
  2345. ; Called from 0x0066 during error conditions or break events
  2346. ; This appears to be a debugging/error reporting mechanism
  2347. ;==============================================================================
  2348. l07b3h:
  2349. ld (011d4h),hl ;07b3 ; Save HL register for later restoration
  2350. ld hl,l07c1h ;07b6 ; Load address of continuation routine
  2351. ex (sp),hl ;07b9 ; Exchange with return address on stack
  2352. retn ;07ba ; Return from interrupt/error
  2353. l07bch:
  2354. ld (011d4h),hl ;07bc ; Save HL register to memory location 011d4h
  2355. pop hl ;07bf ; Restore HL from stack
  2356. dec hl ;07c0 ; Decrement HL (adjust return address or pointer)
  2357. l07c1h:
  2358. ld (011ech),sp ;07c1 ; Save current stack pointer to 011ech
  2359. ld sp,01400h ;07c5 ; Set new stack pointer to 0x1400 (top of RAM)
  2360. call sub_0770h ;07c8 ; Save all CPU registers and setup interrupt mode 2
  2361. ld de,(011eah) ;07cb ; Load DE from memory pointer 011eah
  2362. ld hl,(011f0h) ;07cf ; Load HL from memory pointer 011f0h
  2363. and a ;07d2 ; Clear carry flag for subtraction
  2364. sbc hl,de ;07d3 ; Compare HL and DE (subtract DE from HL)
  2365. jr nz,l07dfh ;07d5 ; If not equal, jump to boot message routine
  2366. ld hl,011d0h ;07d7 ; Point to counter at 011d0h
  2367. dec (hl) ;07da ; Decrement the counter
  2368. jp nz,l0472h ;07db ; If counter not zero, jump to l0472h
  2369. inc (hl) ;07de ; Restore counter (prevent underflow)
  2370. ; =============================================================================
  2371. ; BREAKPOINT/INTERRUPT HANDLER - Display Break Location=
  2372. ; ============================================================================
  2373. ; Purpose: Display "BREAK AT XXXX" message when execution is interrupted
  2374. ; Input: DE contains the address where the break/interrupt occurred
  2375. ; Output: "BREAK AT XXXX" followed by return to monitor prompt
  2376. ; Used by: Breakpoint system, interrupt handlers, debugging features
  2377. ; =============================================================================
  2378. l07dfh: ; Breakpoint Display Handler
  2379. ld hl,l0803h ;07df ; Point to "BREAK AT " message string
  2380. call l00fdh ;07e2 ; Output the "BREAK AT " text to console
  2381. ex de,hl ;07e5 ; DE = address where break occurred
  2382. call sub_06b8h ;07e6 ; Display break address in 4-digit hex (XXXX format)
  2383. call sub_072ah ;07e9 ; Output newline/formatting
  2384. jp l02cch ;07ec ; Return to monitor command prompt
  2385. l07efh:
  2386. push hl ;07ef
  2387. push af ;07f0
  2388. call sub_04ebh ;07f1
  2389. ld hl,(011d6h) ;07f4
  2390. ld a,h ;07f7
  2391. ld i,a ;07f8
  2392. bit 0,l ;07fa
  2393. jr z,l07ffh ;07fc
  2394. ei ;07fe
  2395. l07ffh:
  2396. pop af ;07ff
  2397. pop hl ;0800
  2398. reti ;0801
  2399. l0803h:
  2400. defb 0x42 ;0803 B
  2401. defb 0x52 ;0804 R
  2402. defb 0x45 ;0805 E
  2403. defb 0x41 ;0806 A
  2404. defb 0x4b ;0807 K
  2405. defb 0x20 ;0808
  2406. defb 0x41 ;0809 A
  2407. defb 0x54 ;080a T
  2408. defb 0x20 ;080b
  2409. defb 0x00 ;080c
  2410. sub_080dh:
  2411. ld a,(011f6h) ;080d
  2412. ld c,a ;0810
  2413. call sub_0127h ;0811
  2414. ld hl,01169h ;0814
  2415. ld (011f4h),hl ;0817
  2416. ld b,0ffh ;081a
  2417. l081ch:
  2418. push bc ;081c ; Save character count and buffer position
  2419. call l0134h ;081d ; Get character from input (blocks until available)
  2420. cp 020h ;0820 ; Compare with space character (0x20)
  2421. jr c,l083ch ;0822 ; Jump to special character handler if control character (0x00-0x1F)
  2422. cp 07fh ;0824 ; Compare with DEL character (0x7F)
  2423. jr z,l083ch ;0826 ; Jump to special character handler for DEL (same as backspace)
  2424. ld (hl),a ;0828
  2425. inc hl ;0829
  2426. call sub_0127h ;082a
  2427. pop bc ;082d
  2428. djnz l081ch ;082e
  2429. l0830h:
  2430. ld (hl),00dh ;0830
  2431. call sub_0862h ;0832
  2432. ld hl,01169h ;0835
  2433. ld a,(hl) ;0838
  2434. jp l0677h ;0839
  2435. l083ch:
  2436. pop bc ;083c
  2437. cp 00dh ;083d ; Check for CR (Carriage Return, Enter key)
  2438. jr z,l0830h ;083f ; Jump to end input processing if Enter pressed
  2439. cp 008h ;0841 ; Check for Backspace (0x08) - character deletion
  2440. jr z,l0849h ;0843 ; Jump to backspace handler
  2441. cp 07fh ;0845 ; Check for DEL (0x7F) - alternative character deletion
  2442. jr nz,l081ch ;0847 ; Continue input loop if not a special character
  2443. ;==============================================================================
  2444. ; BACKSPACE/DELETE CHARACTER HANDLER (0x0849)
  2445. ;==============================================================================
  2446. ; Purpose: Handle character deletion during input (Backspace 0x08 or DEL 0x7F)
  2447. ; Implements standard line editing by removing the previous character from both
  2448. ; the input buffer and the terminal display.
  2449. ;
  2450. ; Visual Feedback Sequence:
  2451. ; 1. Send Backspace (0x08) - moves cursor left one position
  2452. ; 2. Send Space (0x20) - overwrites the character with blank
  2453. ; 3. Send Backspace (0x08) - moves cursor back to correct position
  2454. ;
  2455. ; Buffer Management:
  2456. ; - Decrements buffer pointer (HL) to remove character
  2457. ; - Increments remaining character count (B)
  2458. ; - Prevents deletion beyond start of input buffer
  2459. ;
  2460. ; This provides standard terminal line editing behavior expected by users.
  2461. ;==============================================================================
  2462. l0849h:
  2463. ld a,b ;0849 ; Load remaining character count
  2464. inc a ;084a ; Increment to test for buffer underflow
  2465. l084bh:
  2466. jr z,l081ch ;084b ; Jump back to input loop if at buffer start (no chars to delete)
  2467. push bc ;084d ; Save character count and position
  2468. ld c,008h ;084e ; Load Backspace character (0x08)
  2469. call sub_0127h ;0850 ; Send backspace to terminal (move cursor left)
  2470. ld c,020h ;0853 ; Load Space character (0x20)
  2471. call sub_0127h ;0855 ; Send space to terminal (erase character)
  2472. ld c,008h ;0858 ; Load Backspace character (0x08) again
  2473. call sub_0127h ;085a ; Send backspace to terminal (reposition cursor)
  2474. pop bc ;085d ; Restore character count and position
  2475. inc b ;085e ; Increment remaining character count (one less char used)
  2476. dec hl ;085f ; Move buffer pointer back one position
  2477. jr l081ch ;0860 ; Return to main input loop
  2478. ;==============================================================================
  2479. ; NEWLINE OUTPUT ROUTINE (0x0862)
  2480. ;==============================================================================
  2481. ; Purpose: Send carriage return and line feed to console
  2482. ; This routine outputs a proper newline sequence (CR+LF) to move the cursor
  2483. ; to the beginning of the next line on the terminal.
  2484. ;
  2485. ; Input: None
  2486. ; Output: CR (0x0D) followed by LF (0x0A) sent to console
  2487. ; Used by: Console formatting, command completion, line breaks in output
  2488. ;
  2489. ; Technical Details:
  2490. ; • Preserves BC register during operation
  2491. ; • Uses sub_0127h (console output with transmitter ready check)
  2492. ; • Implements standard DOS/Windows-style line ending (CR+LF)
  2493. ; • Essential for proper terminal cursor positioning
  2494. ;==============================================================================
  2495. sub_0862h:
  2496. push bc ;0862 ; Save BC register
  2497. ld c,00dh ;0863 ; Load Carriage Return character (CR, 0x0D)
  2498. call sub_0127h ;0865 ; Send CR to console (move cursor to line start)
  2499. ld c,00ah ;0868 ; Load Line Feed character (LF, 0x0A)
  2500. call sub_0127h ;086a ; Send LF to console (move cursor to next line)
  2501. pop bc ;086d ; Restore BC register
  2502. ret ;086e ; Return
  2503. ;==============================================================================
  2504. ; PORT INPUT/OUTPUT COMMAND (I/O Operations) - (0x086F-0x0886)
  2505. ;==============================================================================
  2506. ; Purpose: Interactive port I/O operations for hardware testing and control
  2507. ; Allows user to read from and write to I/O ports with hex parameters
  2508. ;
  2509. ; Operation:
  2510. ; 1. Check for 'U' modifier (possibly "UP" or "UPDATE" command)
  2511. ; 2. Parse port address from user input
  2512. ; 3. Read current value from port and display it
  2513. ; 4. Prompt user for new value (or 'Q' to quit without change)
  2514. ; 5. If new value provided, write it to the port
  2515. ;
  2516. ; Usage: I PPPP [VV] where PPPP=port address, VV=optional value to write
  2517. ; Interactive: Shows current port value, prompts for new value
  2518. ;==============================================================================
  2519. l086fh: ; Port I/O command entry point
  2520. call sub_065eh ;086f ; Get next character from input buffer
  2521. cp 055h ;0872 ; Check if character is 'U' (0x55)
  2522. jp z,l0924h ;0874 ; If 'U', jump to special U command handler
  2523. call sub_0680h ;0877 ; Parse port address from user input → HL
  2524. ld c,l ;087a ; Load port address low byte into C
  2525. ld b,h ;087b ; Load port address high byte into B
  2526. in a,(c) ;087c ; Read current value from I/O port
  2527. push bc ;087e ; Save port address
  2528. call sub_0708h ;087f ; Display current port value in hex + prompt for input
  2529. pop bc ;0882 ; Restore port address
  2530. ret z ;0883 ; Return if user pressed 'Q' (quit without changes)
  2531. out (c),a ;0884 ; Write new value (from user input) to I/O port
  2532. ret ;0886 ; Return
  2533. ;==============================================================================
  2534. ; ARITHMETIC CALCULATOR COMMAND (+ Addition/Subtraction) - (0x0887-0x089C)
  2535. ;==============================================================================
  2536. ; Purpose: Perform arithmetic operations on two hex values
  2537. ; Calculates both addition (A+B) and subtraction (A-B) results
  2538. ; Displays both results in hex format for comparison
  2539. ;
  2540. ; Operation:
  2541. ; 1. Parse first hex parameter (A)
  2542. ; 2. Parse second hex parameter (B)
  2543. ; 3. Calculate A+B (addition result)
  2544. ; 4. Calculate A-B (subtraction result)
  2545. ; 5. Display both results in hex format
  2546. ;
  2547. ; Usage: + AAAA BBBB (where AAAA and BBBB are hex values)
  2548. ; Output: Shows both sum and difference in hex format
  2549. ;==============================================================================
  2550. l0887h: ; Arithmetic calculator entry point
  2551. call sub_0680h ;0887 ; Parse first hex parameter → HL (value A)
  2552. push hl ;088a ; Save first parameter (A)
  2553. call sub_0680h ;088b ; Parse second hex parameter → HL (value B)
  2554. ex de,hl ;088e ; Move second parameter (B) to DE
  2555. pop hl ;088f ; Restore first parameter (A) to HL
  2556. push hl ;0890 ; Save first parameter again for subtraction
  2557. add hl,de ;0891 ; Calculate A + B (addition)
  2558. call sub_06b8h ;0892 ; Display addition result in hex format
  2559. pop hl ;0895 ; Restore first parameter (A)
  2560. or a ;0896 ; Clear carry flag for subtraction
  2561. sbc hl,de ;0897 ; Calculate A - B (subtraction)
  2562. call sub_06b8h ;0899 ; Display subtraction result in hex format
  2563. jp sub_072ah ;089c ; Add newline and flush output buffer
  2564. ; =============================================================================
  2565. ; LOAD/TRANSFER DATA COMMAND (L command) - Memory/Storage Operations
  2566. ; =============================================================================
  2567. ; Purpose: Load or transfer data between memory locations or external storage
  2568. ; Input: User enters "L" optionally followed by hex parameters
  2569. ; Operation: Performs data loading/transfer operations with address management
  2570. ; Storage: Working address stored at 0x11CD for ongoing operations
  2571. ; Features: Supports data checksums, address calculations, and transfer loops
  2572. ; =============================================================================
  2573. l089fh: ; L Command (Load/Transfer) Entry Point
  2574. call sub_0917h ;089f Initialize/setup routine for load operations
  2575. call sub_0680h ;08a2 Parse optional hex parameter from user input
  2576. jr nz,l08aah ;08a5 If parameter provided, use it as load address
  2577. ld hl,l0000h ;08a7 Default to address 0x0000 if no parameter given
  2578. l08aah: ; Load operation setup
  2579. ld (011cdh),hl ;08aa Store load/transfer address at 0x11CD (working address)
  2580. ld c,011h ;08ad Set up for operations (C=0x11, might be record type/command)
  2581. call sub_099dh ;08af Call data processing routine (load/transfer handler)
  2582. l08b2h: ; Data format parsing loop
  2583. call sub_0997h ;08b2 Get next character from input stream
  2584. cp 03ah ;08b5 Compare with ':' character (0x3A = ASCII colon)
  2585. jr nz,l08b2h ;08b7 Keep searching until ':' found (record start marker)
  2586. call sub_08f8h ;08b9 Parse hex byte (record length/type)
  2587. ld b,a ;08bc Store parsed value in B register (byte count)
  2588. call sub_08efh ;08bd Parse hex address (load destination address)
  2589. or h ;08c0 Check if address is valid (OR with H register)
  2590. or b ;08c1 Check if byte count is valid (OR with B register)
  2591. jr nz,l08cch ;08c2
  2592. call sub_08efh ;08c4
  2593. ld a,013h ;08c7
  2594. jp sub_099dh ;08c9
  2595. l08cch:
  2596. call sub_08f8h ;08cc
  2597. add a,b ;08cf
  2598. add a,l ;08d0
  2599. add a,h ;08d1
  2600. ld c,a ;08d2
  2601. ld de,(011cdh) ;08d3
  2602. add hl,de ;08d7
  2603. l08d8h:
  2604. call sub_08f8h ;08d8
  2605. ld (hl),a ;08db
  2606. inc hl ;08dc
  2607. add a,c ;08dd
  2608. ld c,a ;08de
  2609. djnz l08d8h ;08df
  2610. call sub_08f8h ;08e1
  2611. add a,c ;08e4
  2612. jr z,l08b2h ;08e5
  2613. ld c,013h ;08e7
  2614. call sub_099dh ;08e9
  2615. jp l02d9h ;08ec
  2616. sub_08efh:
  2617. call sub_08f8h ;08ef
  2618. ld h,a ;08f2
  2619. call sub_08f8h ;08f3
  2620. ld l,a ;08f6
  2621. ret ;08f7
  2622. sub_08f8h:
  2623. push bc ;08f8
  2624. call sub_0907h ;08f9
  2625. add a,a ;08fc
  2626. add a,a ;08fd
  2627. add a,a ;08fe
  2628. add a,a ;08ff
  2629. ld b,a ;0900
  2630. call sub_0907h ;0901
  2631. add a,b ;0904
  2632. pop bc ;0905
  2633. ret ;0906
  2634. sub_0907h:
  2635. call sub_0997h ;0907
  2636. cp 030h ;090a
  2637. jr c,sub_0907h ;090c
  2638. cp 03ah ;090e
  2639. jr c,l0914h ;0910
  2640. sub 007h ;0912
  2641. l0914h:
  2642. and 00fh ;0914
  2643. ret ;0916
  2644. sub_0917h:
  2645. call sub_0662h ;0917
  2646. cp 040h ;091a
  2647. jp z,l06ech ;091c
  2648. dec hl ;091f
  2649. ld (011f4h),hl ;0920
  2650. ret ;0923
  2651. l0924h:
  2652. call sub_0917h ;0924
  2653. call sub_0680h ;0927
  2654. push hl ;092a
  2655. call sub_0680h ;092b
  2656. ld c,012h ;092e
  2657. call sub_099dh ;0930
  2658. pop de ;0933
  2659. l0934h:
  2660. push hl ;0934
  2661. ld b,010h ;0935
  2662. and a ;0937
  2663. sbc hl,de ;0938
  2664. jr c,l0970h ;093a
  2665. ld a,h ;093c
  2666. and a ;093d
  2667. jr nz,l0946h ;093e
  2668. ld a,l ;0940
  2669. cp b ;0941
  2670. jr nc,l0946h ;0942
  2671. ld b,a ;0944
  2672. inc b ;0945
  2673. l0946h:
  2674. ex de,hl ;0946
  2675. ld c,03ah ;0947
  2676. call sub_099dh ;0949
  2677. ld a,b ;094c
  2678. call sub_0985h ;094d
  2679. add a,h ;0950
  2680. add a,l ;0951
  2681. ld c,a ;0952
  2682. call sub_098ah ;0953
  2683. sub a ;0956
  2684. call sub_0985h ;0957
  2685. l095ah:
  2686. ld a,(hl) ;095a
  2687. call sub_0985h ;095b
  2688. add a,c ;095e
  2689. ld c,a ;095f
  2690. inc hl ;0960
  2691. djnz l095ah ;0961
  2692. ld a,c ;0963
  2693. neg ;0964
  2694. call sub_0985h ;0966
  2695. pop de ;0969
  2696. ex de,hl ;096a
  2697. call sub_074dh ;096b
  2698. jr l0934h ;096e
  2699. l0970h:
  2700. pop hl ;0970
  2701. ld c,03ah ;0971
  2702. call sub_099dh ;0973
  2703. ld b,00ah ;0976
  2704. ld c,030h ;0978
  2705. l097ah:
  2706. call sub_099dh ;097a
  2707. djnz l097ah ;097d
  2708. ld c,014h ;097f
  2709. call sub_099dh ;0981
  2710. ret ;0984
  2711. sub_0985h:
  2712. call sub_06c6h ;0985
  2713. jr l098dh ;0988
  2714. sub_098ah:
  2715. call sub_06b8h ;098a
  2716. l098dh:
  2717. push hl ;098d
  2718. ld hl,(011f2h) ;098e
  2719. dec hl ;0991
  2720. ld (011f2h),hl ;0992
  2721. pop hl ;0995
  2722. ret ;0996
  2723. sub_0997h:
  2724. push bc ;0997
  2725. call l0116h ;0998
  2726. pop bc ;099b
  2727. ret ;099c
  2728. sub_099dh:
  2729. push bc ;099d
  2730. call sub_0111h ;099e
  2731. pop bc ;09a1 ; Restore BC register
  2732. ret ;09a2 ; Return from routine
  2733. ;==============================================================================
  2734. ; CONTROL CHARACTER HANDLER (0x09A3)
  2735. ;==============================================================================
  2736. ; Purpose: Process special control characters during input operations
  2737. ; This routine intercepts and handles special ASCII control characters that
  2738. ; require immediate system response, providing user control over operations.
  2739. ;
  2740. ; Control Characters Handled:
  2741. ; • 0x03 (ETX, Ctrl+C): Emergency system reset/break
  2742. ; • 0x13 (XOFF, Ctrl+S): Pause/resume output flow control
  2743. ;
  2744. ; Character Processing:
  2745. ; 1. Call input routine (sub_013ah) to get character
  2746. ; 2. Check for zero (no character available)
  2747. ; 3. Compare with control character codes
  2748. ; 4. Take appropriate action or return
  2749. ;
  2750. ; Flow Control Features:
  2751. ; • Preserves BC register across all operations
  2752. ; • Returns immediately if no character or unrecognized character
  2753. ; • Provides clean stack management for nested calls
  2754. ; • Implements standard terminal control behavior
  2755. ;==============================================================================
  2756. sub_09a3h:
  2757. push bc ;09a3 ; Save BC register
  2758. call sub_013ah ;09a4 ; Get character from input (keyboard/serial)
  2759. pop bc ;09a7 ; Restore BC register
  2760. ret z ;09a8 ; Return if no character available (zero flag set)
  2761. cp 003h ;09a9 ; Check for ETX (End of Text, Ctrl+C)
  2762. jr z,l09b6h ;09ab ; Jump to system reset if Ctrl+C pressed
  2763. cp 013h ;09ad ; Check for XOFF (Ctrl+S, pause)
  2764. ret nz ;09af ; Return if not XOFF
  2765. push bc ;09b0 ; Save BC register
  2766. call l0134h ;09b1 ; Handle XOFF (pause/resume) functionality
  2767. pop bc ;09b4 ; Restore BC register
  2768. ret ;09b5 ; Return from XOFF handling
  2769. ;==============================================================================
  2770. ; SYSTEM RESET/RESTART ROUTINE (0x09B6)
  2771. ;==============================================================================
  2772. ; Purpose: Emergency system reset triggered by Ctrl+C (ETX) character
  2773. ; This routine provides a clean way to abort current operations and return
  2774. ; to the monitor command prompt, similar to a "break" or "interrupt" function.
  2775. ;
  2776. ; Trigger Conditions:
  2777. ; • Ctrl+C (0x03 ETX character) received during input processing
  2778. ; • User wants to abort current operation and return to monitor
  2779. ; • Emergency recovery from hung or problematic operations
  2780. ;
  2781. ; Reset Actions:
  2782. ; 1. Reset stack pointer to system default (0x1400)
  2783. ; 2. Jump directly to main monitor command loop
  2784. ; 3. Bypass any pending operations or nested calls
  2785. ;
  2786. ; Technical Details:
  2787. ; • Stack Reset: SP = 0x1400 (top of RAM workspace)
  2788. ; • Direct Jump: Goes to 0x02CC (main monitor loop entry)
  2789. ; • Clean State: Abandons current call stack and variables
  2790. ; • User Interface: Provides immediate return to ">" prompt
  2791. ;
  2792. ; This implements a standard "Ctrl+C break" behavior found in many systems
  2793. ; of this era, allowing users to escape from problematic situations.
  2794. ;==============================================================================
  2795. l09b6h:
  2796. ld sp,01400h ;09b6 ; Reset stack pointer to system default
  2797. jp l02cch ;09b9 ; Jump to main monitor command loop (clean restart)
  2798. ;==============================================================================
  2799. ; FLOPPY DISK CONTROLLER COMMAND HANDLER (O COMMAND) (0x09BC-0x0A5E)
  2800. ;==============================================================================
  2801. ; Purpose: Comprehensive floppy disk operation command with multi-sector support
  2802. ; The O command is the primary interface for all floppy disk operations including
  2803. ; read, write, format, and seek operations with automatic multi-sector handling.
  2804. ;
  2805. ; COMMAND SYNTAX:
  2806. ; O D F T S - Disk parameter configuration only
  2807. ; OS - Special CP/M boot operation (jumps to 0x0FBB)
  2808. ;
  2809. ; PARAMETER SPECIFICATION:
  2810. ; • D (Drive): 0-3 (selects physical floppy drive A: through D:)
  2811. ; • F (Flags): 0-1 (drive control/head selection: 0=standard, 1=alternate)
  2812. ; • T (Track): 0-76 (track/cylinder number, max 77 tracks for 8" drives)
  2813. ; • S (Sectors): 1-26 (sector count per operation, max 27 sectors/track)
  2814. ;
  2815. ; IMPORTANT: O command only configures disk parameters. Memory addressing
  2816. ; is controlled by subsequent R (read) or W (write) commands.
  2817. ;
  2818. ; OPERATION MODES:
  2819. ; 1. SETUP MODE (default): Configures disk parameters for later R/W operations
  2820. ; 2. SEEK MODE: If S=0, performs head positioning without data transfer
  2821. ; 3. BOOT MODE: "OS" variant initiates CP/M system boot sequence
  2822. ;
  2823. ; ADVANCED FEATURES:
  2824. ; • Automatic multi-sector transfers across track boundaries
  2825. ; • Sector increment with track wraparound (sector 27 → track+1, sector 1)
  2826. ; • Head selection toggle for double-sided drives (controlled by drive status)
  2827. ; • Memory buffer overflow protection (stops at end address)
  2828. ; • Error recovery with "DISK ERR" message display
  2829. ;
  2830. ; MEMORY PARAMETER STORAGE:
  2831. ; • 0x1202: Drive number (0-3) - Selects active drive unit
  2832. ; • 0x1226: Drive control flags (0-1) - Head/side selection
  2833. ; • 0x1225: Track/cylinder number (0-76) - Current track position
  2834. ; • 0x1227: Sector count (1-26) - Number of sectors to transfer
  2835. ; • 0x1200-0x1201: DMA buffer address (16-bit) - Target memory location
  2836. ; • 0x11F7: Operation ready flag (0xFF when parameters validated)
  2837. ; • 0x11F8: Function pointer - Points to operation handler routine
  2838. ;
  2839. ; EXECUTION FLOW:
  2840. ; 1. Parameter validation and range checking (drive 0-3, track 0-76, etc.)
  2841. ; 2. Memory address parsing and buffer setup (start/end address validation)
  2842. ; 3. Multi-sector loop with automatic sector/track increment
  2843. ; 4. DMA buffer management and overflow protection
  2844. ; 5. Error handling with user-friendly "DISK ERR" messages
  2845. ;
  2846. ; HARDWARE INTERFACE:
  2847. ; • NEC µPD765A FDC via ports 0xF0-0xF6 for command/data/status
  2848. ; • Z80 DMA controller via port 0xF3 for high-speed transfers
  2849. ; • Drive selection via hardware control lines
  2850. ; • Track positioning via stepper motor control
  2851. ;
  2852. ; ERROR CONDITIONS:
  2853. ; • Invalid drive number (>3): "ERR" message, return to monitor
  2854. ; • Invalid track number (>76): "ERR" message, return to monitor
  2855. ; • Invalid sector count (0 or >26): "ERR" message, return to monitor
  2856. ; • Disk hardware failure: "DISK ERR" message, return to monitor
  2857. ; • Memory buffer overflow: Operation stops at end address
  2858. ;
  2859. ; SPECIAL OPERATIONS:
  2860. ; • "OS" command: Bypasses normal parameter parsing, jumps directly to CP/M boot
  2861. ; • Zero sector count: Performs seek operation without data transfer
  2862. ; • Single sector: Standard read/write operation
  2863. ; • Multi-sector: Automatic sector increment with track boundary handling
  2864. ;
  2865. ; EXAMPLES:
  2866. ; O 0 0 5 1 - Configure drive A:, track 5, 1 sector (then use R/W for memory)
  2867. ; O 1 0 0 10 - Configure drive B:, track 0, 10 sectors (then use R/W for memory)
  2868. ; O 0 1 10 0 - Seek drive A: to track 10 (no data transfer)
  2869. ; OS - Boot CP/M operating system from disk
  2870. ;
  2871. ; TYPICAL USAGE SEQUENCE:
  2872. ; O 0 0 5 1 - Configure: Drive A:, track 5, 1 sector
  2873. ; R 1000 100 - Execute: Read data into memory 1000h-10FFh
  2874. ;==============================================================================
  2875. l09bch: ; Floppy Disk Parameter Parser Entry Point
  2876. call sub_065eh ;09bc Get next character from input buffer
  2877. cp 053h ;09bf Compare with 'S' (0x53 = ASCII 'S' for special command)
  2878. jp z,l0fbbh ;09c1 If 'S', jump to special disk handler
  2879. call sub_0680h ;09c4 Parse hex parameter (drive number)
  2880. cp 004h ;09c7 Check if drive number >= 4 (invalid)
  2881. jp nc,l02d9h ;09c9 Jump to error if invalid drive number
  2882. ld (01202h),a ;09cc Store valid drive number (0-3)
  2883. call sub_0680h ;09cf Get next parameter from input
  2884. cp 002h ;09d2 Check if parameter < 2 (valid range)
  2885. jp nc,l02d9h ;09d4 Jump to error if parameter >= 2
  2886. ld (01226h),a ;09d7 Store drive control flags (0 or 1)
  2887. call sub_0680h ;09da Get next parameter from input
  2888. cp 04dh ;09dd Check if parameter < 77 (0x4D, max tracks)
  2889. jp nc,l02d9h ;09df Jump to error if parameter >= 77
  2890. ld (01225h),a ;09e2 Store drive parameter/selector (track/cylinder)
  2891. call sub_0680h ;09e5 Parse final parameter (sector count)
  2892. or a ;09e8 Check if sector count is zero (invalid)
  2893. jp z,l02d9h ;09e9 Jump to error if zero sectors specified
  2894. cp 01bh ;09ec Check if sector count >= 27 (0x1B, max sectors)
  2895. jp nc,l02d9h ;09ee Jump to error if too many sectors
  2896. ld (01227h),a ;09f1 Store valid sector count (1-26)
  2897. ld a,0ffh ;09f4 Load 0xFF (operation ready flag)
  2898. ld (011f7h),a ;09f6 Set operation status flag (ready for disk operations)
  2899. ret ;09f9 Return to caller with parameters validated and stored
  2900. ;==============================================================================
  2901. ; DISK WRITE COMMAND HANDLER (W COMMAND) (0x09FA-0x09FE)
  2902. ;
  2903. ; Purpose: Simplified disk write operation using disk parameters from O command
  2904. ; This command writes data from memory to floppy disk using disk parameters
  2905. ; previously configured by the O command, while controlling memory addressing.
  2906. ;
  2907. ; Syntax: W AAAA BBBB
  2908. ; Where: AAAA = Start address of data to write to disk
  2909. ; BBBB = Length of data to write (number of bytes)
  2910. ;
  2911. ; Prerequisite: O command must be used first to configure disk parameters
  2912. ; (drive number, track, sector count, etc.)
  2913. ;
  2914. ; Operation:
  2915. ; 1. Checks that disk parameters are configured (O command was run)
  2916. ; 2. Parses memory address and length from W command parameters
  2917. ; 3. Uses sub_0bf2h which configures FDC for write operations (command 0x04)
  2918. ; 4. Combines O command disk params with W command memory params for actual I/O
  2919. ;
  2920. ; Related Commands:
  2921. ; - O command (0x09BC): Configures disk parameters (drive, track, sectors)
  2922. ; - R command (0x09FF): Disk read using O parameters + R memory parameters
  2923. ;==============================================================================
  2924. ld hl,l0db1h ;09fa W COMMAND: Load pointer to write parameter block
  2925. jr l0a0ah ;09fd Jump to common disk operation handler
  2926. ;==============================================================================
  2927. ; DISK READ COMMAND HANDLER (R COMMAND) (0x09FF-0x0A09)
  2928. ;
  2929. ; Purpose: Simplified disk read operation using disk parameters from O command
  2930. ; This command reads data from floppy disk to memory using disk parameters
  2931. ; previously configured by the O command, while controlling memory addressing.
  2932. ;
  2933. ; Syntax: R AAAA BBBB
  2934. ; Where: AAAA = Start address to store data read from disk
  2935. ; BBBB = Length of data to read (number of bytes)
  2936. ;
  2937. ; Prerequisite: O command must be used first to configure disk parameters
  2938. ; (drive number, track, sector count, etc.)
  2939. ;
  2940. ; Operation:
  2941. ; 1. Checks for 'O' character (alternate entry point to O command)
  2942. ; 2. Verifies that disk parameters are configured (O command was run)
  2943. ; 3. Parses memory address and length from R command parameters
  2944. ; 4. Uses sub_0d2eh which calls sub_0bf2h then validates read status
  2945. ; 5. Combines O command disk params with R command memory params for actual I/O
  2946. ;==============================================================================
  2947. ld hl,l0db1h ;09fa
  2948. jr l0a0ah ;09fd
  2949. call sub_065eh ;09ff R COMMAND: Check if parameters are provided
  2950. cp 04fh ;0a02 Compare with 'O' character (alternate O command entry)
  2951. jp z,l089fh ;0a04 Jump to O command handler if 'O' character found
  2952. ld hl,l0dabh ;0a07 Load pointer to read parameter block
  2953. l0a0ah:
  2954. ;==============================================================================
  2955. ; COMMON DISK OPERATION HANDLER (0x0A0A+)
  2956. ;
  2957. ; Purpose: Shared entry point for both R and W commands
  2958. ; Handles parameter validation and initiates disk I/O operations
  2959. ;
  2960. ; Input: HL = Pointer to parameter block (0x0DAB for read, 0x0DB1 for write)
  2961. ; Uses: FDC command bytes (0x03 = READ DATA, 0x04 = WRITE DATA)
  2962. ;
  2963. ; This routine validates the operation status, parses memory addresses,
  2964. ; and coordinates with the NEC µPD765A floppy disk controller.
  2965. ;==============================================================================
  2966. ld (011f8h),hl ;0a0a Store parameter block pointer
  2967. ld hl,011f7h ;0a0d
  2968. xor a ;0a10
  2969. cp (hl) ;0a11
  2970. jp z,l02d9h ;0a12
  2971. ld (hl),a ;0a15
  2972. call l0de0h ;0a16
  2973. call sub_0680h ;0a19
  2974. push hl ;0a1c
  2975. call sub_0680h ;0a1d
  2976. pop de ;0a20
  2977. ex de,hl ;0a21
  2978. l0a22h:
  2979. or a ;0a22
  2980. inc hl ;0a23
  2981. sbc hl,de ;0a24
  2982. add hl,de ;0a26
  2983. dec hl ;0a27
  2984. ret nc ;0a28
  2985. ld (01200h),hl ;0a29
  2986. push de ;0a2c
  2987. push hl ;0a2d
  2988. ld hl,(011f8h) ;0a2e
  2989. call sub_0da8h ;0a31
  2990. jr nc,l0a60h ;0a34
  2991. ld hl,01227h ;0a36
  2992. ld a,(hl) ;0a39
  2993. inc a ;0a3a
  2994. ld (hl),a ;0a3b
  2995. cp 01bh ;0a3c
  2996. jr c,l0a51h ;0a3e
  2997. ld (hl),001h ;0a40
  2998. ld a,(01203h) ;0a42
  2999. or a ;0a45
  3000. jr z,l0a4dh ;0a46
  3001. dec hl ;0a48
  3002. ld a,(hl) ;0a49
  3003. xor 001h ;0a4a
  3004. ld (hl),a ;0a4c
  3005. l0a4dh:
  3006. jr nz,l0a51h ;0a4d
  3007. dec hl ;0a4f
  3008. inc (hl) ;0a50
  3009. l0a51h:
  3010. ld a,(01203h) ;0a51
  3011. or a ;0a54
  3012. ld hl,l0080h ;0a55
  3013. jr z,l0a5bh ;0a58
  3014. add hl,hl ;0a5a
  3015. l0a5bh:
  3016. pop de ;0a5b
  3017. add hl,de ;0a5c
  3018. pop de ;0a5d
  3019. jr l0a22h ;0a5e
  3020. l0a60h:
  3021. ld hl,l0a69h ;0a60
  3022. call l00fdh ;0a63
  3023. jp l02d9h ;0a66
  3024. l0a69h:
  3025. defb 0x44 ;0a69 D
  3026. defb 0x49 ;0a6a I
  3027. defb 0x53 ;0a6b S
  3028. defb 0x4b ;0a6c K
  3029. defb 0x20 ;0a6d
  3030. defb 0x45 ;0a6e E
  3031. defb 0x52 ;0a6f R
  3032. defb 0x52 ;0a70 R
  3033. defb 0x0d ;0a71 RETURN
  3034. defb 0x0a ;0a72 RETURN
  3035. defb 0x00 ;0a73
  3036. l0a74h:
  3037. call sub_0680h ;0a74 Get drive number parameter from user input
  3038. cp 004h ;0a77 Check if drive number >= 4 (invalid)
  3039. jp nc,l02d9h ;0a79 Jump to error if invalid drive number
  3040. ld (01202h),a ;0a7c Store current drive number (0-3)
  3041. call sub_0e43h ;0a7f Execute drive operation
  3042. jp nc,l0a60h ;0a82
  3043. ret ;0a85
  3044. l0a86h:
  3045. call sub_0acbh ;0a86
  3046. jp nc,l0a60h ;0a89
  3047. ret ;0a8c
  3048. ;==============================================================================
  3049. ; FLOPPY DISK CONTROLLER INITIALIZATION (0x0A8D)
  3050. ;==============================================================================
  3051. ; Purpose: Initialize NEC µPD765A floppy disk controller and Z80 DMA
  3052. ; Hardware Setup:
  3053. ; - Port 0xF6: FDC command/status register
  3054. ; - Port 0xF3: Z80 DMA control register (standalone Z80 DMA chip)
  3055. ; - Port 0xF0: FDC main status register
  3056. ; - Port 0xF4: FDC data register
  3057. ;
  3058. ; Z80 DMA Operations:
  3059. ; - Value 0x08: Enable Z80 DMA for floppy transfers
  3060. ; - Clear bit 3: Modify DMA transfer mode parameters
  3061. ; - Two-stage DMA setup for optimal transfer configuration
  3062. ;
  3063. ; Operation:
  3064. ; 1. Send "specify" command to FDC (configure timing parameters)
  3065. ; 2. Enable Z80 DMA controller for high-speed transfers
  3066. ; 3. Modify DMA transfer mode settings
  3067. ; 4. Wait for FDC ready status
  3068. ; 5. Configure for read/write operations
  3069. ;
  3070. ; Returns: Carry flag set if successful, clear if failed
  3071. ;==============================================================================
  3072. sub_0a8dh:
  3073. ld a,003h ;0a8d ; Load FDC "specify" command
  3074. out (0f6h),a ;0a8f ; Send command to FDC command register
  3075. ld a,008h ;0a91 ; Load Z80 DMA enable control value
  3076. out (0f3h),a ;0a93 ; Enable Z80 DMA for floppy operations
  3077. res 3,a ;0a95 ; Clear bit 3 (modify DMA transfer mode)
  3078. out (0f3h),a ;0a97 ; Update Z80 DMA control register
  3079. ld bc,sub_011ch ;0a99 ; Load timeout/delay parameters
  3080. call sub_0f0ah ;0a9c ; Call delay/timing routine
  3081. ld bc,l0000h ;0a9f ; Initialize counter for FDC status polling
  3082. ;==============================================================================
  3083. ; FDC STATUS POLLING LOOP (0x0AA2)
  3084. ;==============================================================================
  3085. ; Purpose: Wait for FDC to become ready for command execution
  3086. ; This is a critical timing loop that ensures the NEC µPD765A FDC is ready
  3087. ; to accept commands before proceeding with disk operations.
  3088. ;
  3089. ; Hardware Details:
  3090. ; - Port 0xF0: NEC µPD765A Main Status Register (MSR)
  3091. ; - Bit 7 of MSR: RQM (Request for Master) - indicates FDC ready state
  3092. ; - Timeout: 65536 iterations (BC=0x0000 decrements to 0xFFFF then 0x0000)
  3093. ;
  3094. ; Status Register Interpretation:
  3095. ; - MSR bit 7 = 1: FDC ready to accept commands/data
  3096. ; - MSR bit 7 = 0: FDC busy, continue polling
  3097. ; - Expected final state: MSR = 0x80 (only RQM bit set)
  3098. ;
  3099. ; Returns:
  3100. ; - Zero flag set: Timeout occurred (FDC never became ready)
  3101. ; - Zero flag clear: FDC ready, A contains final status
  3102. ; - A = 0x00: Success (MSR was exactly 0x80)
  3103. ; - A ≠ 0x00: Warning (MSR had unexpected bits set)
  3104. ;==============================================================================
  3105. l0aa2h:
  3106. dec bc ;0aa2 ; Decrement timeout counter
  3107. ld a,b ;0aa3 ; Load high byte of counter
  3108. or c ;0aa4 ; OR with low byte to test for zero
  3109. ret z ;0aa5 ; Return if timeout (BC reached 0x0000)
  3110. in a,(0f0h) ;0aa6 ; Read FDC Main Status Register
  3111. bit 7,a ;0aa8 ; Test RQM bit (Request for Master)
  3112. jr z,l0aa2h ;0aaa ; Loop if FDC not ready (RQM=0)
  3113. xor 080h ;0aac ; XOR with 0x80 to check if only RQM bit set
  3114. ret nz ;0aae ; Return if other status bits are set (error condition)
  3115. ;==============================================================================
  3116. ; FDC COMMAND EXECUTION SETUP (0x0AAF)
  3117. ;==============================================================================
  3118. ; Purpose: Execute FDC commands and wait for completion status
  3119. ; This section handles the command execution phase after the FDC is ready.
  3120. ; It coordinates with the NEC µPD765A to execute disk operations.
  3121. ;
  3122. ; Operation Flow:
  3123. ; 1. Call command execution routine (sub_0ba7h)
  3124. ; 2. Wait for command completion (status 0x80)
  3125. ; 3. Setup interrupt vector for DMA completion
  3126. ; 4. Configure DMA parameters for data transfer
  3127. ;
  3128. ; Hardware Configuration:
  3129. ; - Port 0xF4: FDC data register for parameter passing
  3130. ; - Port 0xF6: FDC command register
  3131. ; - Memory 0x1334: Interrupt vector table pointer
  3132. ; - Address 0x0BB6: DMA completion handler
  3133. ;
  3134. ; Status Codes:
  3135. ; - 0x80: Command execution successful, ready for data transfer
  3136. ; - Other: Command still executing or error condition
  3137. ;==============================================================================
  3138. l0aafh:
  3139. call sub_0ba7h ;0aaf ; Execute FDC command sequence
  3140. ret nc ;0ab2 ; Return if command execution failed
  3141. cp 080h ;0ab3 ; Check if execution status is 0x80 (success)
  3142. jr nz,l0aafh ;0ab5 ; Loop until command completes successfully
  3143. ld hl,l0bb6h ;0ab7 ; Load address of DMA completion handler
  3144. ld (01334h),hl ;0aba ; Store in interrupt vector table
  3145. ld a,030h ;0abd ; Load DMA control parameter
  3146. out (0f4h),a ;0abf ; Send to FDC data register
  3147. ld a,0d7h ;0ac1 ; Load FDC command parameter
  3148. out (0f6h),a ;0ac3 ; Send command to FDC
  3149. ld a,001h ;0ac5 ; Load final parameter
  3150. out (0f6h),a ;0ac7 ; Complete command sequence
  3151. scf ;0ac9 ; Set carry flag (success indicator)
  3152. ret ;0aca ; Return with success status
  3153. ;==============================================================================
  3154. ; FLOPPY DISK CONTROLLER MASTER ROUTINE (0x0ACB)
  3155. ;==============================================================================
  3156. ; Purpose: Main floppy disk operation coordinator
  3157. ; Calls sub-routines to:
  3158. ; 1. Initialize FDC and prepare for disk operations (sub_0a8dh)
  3159. ; 2. Execute disk read/write operations (sub_0ae9h)
  3160. ; 3. Loop through multiple drives/sectors (0x0AD8 loop)
  3161. ;
  3162. ; This appears to be the high-level disk I/O interface that coordinates
  3163. ; multiple disk operations across different drives (up to 4 drives/sectors)
  3164. ;==============================================================================
  3165. sub_0acbh:
  3166. call sub_0a8dh ;0acb ; Initialize FDC hardware and prepare for operation
  3167. ret nc ;0ace ; Return if FDC initialization failed
  3168. call sub_0ae9h ;0acf ; Execute the actual disk operation
  3169. ret nc ;0ad2
  3170. xor a ;0ad3 A = 0 (start with drive 0)
  3171. ld iy,01205h ;0ad4 Point IY to drive status table
  3172. l0ad8h: ; Multi-drive boot loop (tries drives 0,1,2,3)
  3173. push af ;0ad8 Save current drive number
  3174. ld (01202h),a ;0ad9 Set current drive number (0x1202)
  3175. call sub_0b1ch ;0adc Attempt to read boot sector from current drive
  3176. pop af ;0adf Restore drive number
  3177. inc iy ;0ae0 Move to next drive status entry
  3178. inc a ;0ae2 Next drive number (0→1→2→3)
  3179. cp 004h ;0ae3 Check if tried all 4 drives
  3180. jr nz,l0ad8h ;0ae5 Loop until all drives tested
  3181. scf ;0ae7 Set carry flag (success)
  3182. ret ;0ae8 Return from multi-drive scan
  3183. ;==============================================================================
  3184. ; FDC COMMAND PARAMETER SETUP (0x0AE9)
  3185. ;==============================================================================
  3186. ; Purpose: Prepare NEC µPD765A command parameters for disk operations
  3187. ; This routine builds the command parameter block required by the FDC to
  3188. ; execute read/write operations. The parameters are assembled from various
  3189. ; system variables and formatted according to NEC µPD765A specifications.
  3190. ;
  3191. ; Memory Layout - FDC Parameter Block (0x1213-0x1215):
  3192. ; • 0x1213: Command byte (0x03 = READ DATA command)
  3193. ; • 0x1214: Drive/Head selection and DMA control
  3194. ; • 0x1215: Track/Sector/Size parameters
  3195. ;
  3196. ; Parameter Sources:
  3197. ; • 0x120B: Drive geometry configuration (tracks, density)
  3198. ; • 0x120A: Head selection and DMA mode settings
  3199. ; • 0x1209: Sector size and format parameters
  3200. ; • 0x1204: Additional drive control flags
  3201. ;
  3202. ; NEC µPD765A Command Format:
  3203. ; - Bit manipulation ensures proper head selection and DMA modes
  3204. ; - Rotation and masking operations format multi-bit parameters
  3205. ; - Command block follows standard FDC command structure
  3206. ;==============================================================================
  3207. sub_0ae9h:
  3208. ld hl,01213h ;0ae9 ; Point to FDC command parameter block
  3209. push hl ;0aec ; Save base pointer for later use
  3210. ld (hl),003h ;0aed ; Set command byte: 0x03 = READ DATA command
  3211. inc hl ;0aef ; Move to drive/head parameter byte (0x1214)
  3212. ld a,(0120bh) ;0af0 ; Load drive geometry configuration
  3213. and 00fh ;0af3 ; Mask to get lower 4 bits (drive geometry)
  3214. sub 011h ;0af5 ; Subtract 0x11 (adjust for FDC format)
  3215. cpl ;0af7 ; Complement bits (invert for FDC encoding)
  3216. rlca ;0af8 ; Rotate left 4 positions to place in upper nibble
  3217. rlca ;0af9 ; (4 rotations = shift left 4 bits)
  3218. rlca ;0afa
  3219. rlca ;0afb
  3220. ld (hl),a ;0afc ; Store formatted drive parameter
  3221. ld a,(0120ah) ;0afd ; Load head selection and DMA mode
  3222. rrca ;0b00 ; Rotate right 4 positions to get lower nibble
  3223. rrca ;0b01 ; (4 rotations = shift right 4 bits)
  3224. rrca ;0b02
  3225. rrca ;0b03
  3226. and 00fh ;0b04 ; Mask to keep only lower 4 bits
  3227. or (hl) ;0b06 ; Combine with previous drive parameter
  3228. ld (hl),a ;0b07 ; Store combined drive/head parameter
  3229. inc hl ;0b08 ; Move to track/sector parameter byte (0x1215)
  3230. ld a,(01209h) ;0b09 ; Load sector size and format configuration
  3231. res 0,a ;0b0c ; Clear bit 0 (modify sector size encoding)
  3232. ld (hl),a ;0b0e ; Store modified sector parameter
  3233. ld a,(01204h) ;0b0f ; Load additional drive control flags
  3234. and 001h ;0b12 ; Mask to get only bit 0 (specific control flag)
  3235. or (hl) ;0b14 ; Combine with sector parameter
  3236. ld (hl),a ;0b15 ; Store final track/sector/control parameter
  3237. ld b,003h ;0b16 ; Set parameter count: 3 bytes for FDC command
  3238. pop hl ;0b18 ; Restore base pointer to command block
  3239. jp l0b64h ;0b19 ; Jump to FDC command execution routine
  3240. ;==============================================================================
  3241. ; FDC OPERATION WITH PARAMETER MANAGEMENT (0x0B1C)
  3242. ;==============================================================================
  3243. ; Purpose: Execute FDC operations with automatic parameter backup/restore
  3244. ; This routine provides a higher-level interface for disk operations that
  3245. ; temporarily modifies drive parameters and ensures they are properly restored
  3246. ; even if the operation fails.
  3247. ;
  3248. ; Operation Flow:
  3249. ; 1. Prepare FDC for operation (sub_0b33h)
  3250. ; 2. Backup current drive parameter (0x1225)
  3251. ; 3. Set temporary parameter (0x03) for operation
  3252. ; 4. Execute disk operation (sub_0c05h)
  3253. ; 5. Restore original parameter regardless of operation result
  3254. ; 6. Verify FDC is ready for next operation
  3255. ;
  3256. ; Memory Locations:
  3257. ; • 0x1225: Drive parameter/selector register (backed up and restored)
  3258. ; • Value 0x03: Temporary parameter setting for this operation type
  3259. ;
  3260. ; Error Handling:
  3261. ; - Parameters are restored even if disk operation fails
  3262. ; - Final FDC readiness check before returning
  3263. ; - Carry flag indicates overall operation success
  3264. ;==============================================================================
  3265. sub_0b1ch:
  3266. call sub_0b33h ;0b1c ; Prepare FDC for operation
  3267. ld a,(01225h) ;0b1f ; Load current drive parameter
  3268. push af ;0b22 ; Save parameter on stack for restoration
  3269. ld a,003h ;0b23 ; Load temporary parameter value
  3270. ld (01225h),a ;0b25 ; Set temporary drive parameter
  3271. call sub_0c05h ;0b28 ; Execute disk operation
  3272. pop af ;0b2b ; Restore original parameter from stack
  3273. ld (01225h),a ;0b2c ; Write back original drive parameter
  3274. call sub_0b33h ;0b2f ; Verify FDC readiness after operation
  3275. ret c ;0b32 ; Return if FDC is ready (carry set = success)
  3276. ;==============================================================================
  3277. ; FDC RECALIBRATE AND COMMAND SETUP (0x0B33)
  3278. ;==============================================================================
  3279. ; Purpose: Prepare FDC for operation with recalibrate command and status monitoring
  3280. ; This routine initializes the FDC to a known state and sets up a recalibrate
  3281. ; command for reliable disk operations. Used both before and after disk operations
  3282. ; to ensure the drive heads are properly positioned.
  3283. ;
  3284. ; Operation Sequence:
  3285. ; 1. Set drive status to 0xFF (reset/initialize state)
  3286. ; 2. Execute low-level FDC preparation (sub_0d2eh)
  3287. ; 3. Clear status flags and setup command parameters
  3288. ; 4. Configure RECALIBRATE command (0x07) with drive parameters
  3289. ; 5. Wait for command completion with timeout monitoring
  3290. ;
  3291. ; Hardware Details:
  3292. ; • IY register: Points to drive status table (set by caller)
  3293. ; • 0x1226: Drive control flags cleared during operation
  3294. ; • 0x1213: Command byte set to 0x07 (RECALIBRATE command)
  3295. ; • 0x124A: Operation completion status flag
  3296. ;
  3297. ; NEC µPD765A RECALIBRATE Command:
  3298. ; - Moves drive head to track 0 (cylinder 0)
  3299. ; - Establishes known reference position for subsequent seeks
  3300. ; - Required after drive selection or power-on sequences
  3301. ;==============================================================================
  3302. sub_0b33h:
  3303. ld (iy+000h),0ffh ;0b33 ; Set drive status to 0xFF (initialize state)
  3304. call sub_0d2eh ;0b37 ; Execute low-level FDC preparation routine
  3305. ret nc ;0b3a ; Return if FDC preparation failed (carry clear)
  3306. xor a ;0b3b ; Load 0 into accumulator
  3307. ld (01226h),a ;0b3c ; Clear drive control flags
  3308. ld hl,01213h ;0b3f ; Point to FDC command parameter block
  3309. push hl ;0b42 ; Save command block pointer
  3310. ld (hl),007h ;0b43 ; Set command byte: 0x07 = RECALIBRATE command
  3311. inc hl ;0b45 ; Move to next parameter byte
  3312. call sub_0b7bh ;0b46 ; Setup additional command parameters
  3313. xor a ;0b49 ; Load 0 into accumulator
  3314. ld (0124ah),a ;0b4a ; Clear operation completion status flag
  3315. ld b,002h ;0b4d ; Set parameter count: 2 bytes for RECALIBRATE command
  3316. pop hl ;0b4f ; Restore command block pointer
  3317. call l0b64h ;0b50 ; Send command to FDC
  3318. ret nc ;0b53 ; Return if command transmission failed
  3319. ;==============================================================================
  3320. ; RECALIBRATE COMPLETION MONITORING (0x0B54)
  3321. ;==============================================================================
  3322. ; Purpose: Wait for RECALIBRATE command completion with status validation
  3323. ; Monitors the operation completion flag and validates the final status to
  3324. ; ensure the recalibrate operation completed successfully.
  3325. ;
  3326. ; Status Monitoring:
  3327. ; • 0x124A: Operation completion flag (0=pending, non-zero=completed)
  3328. ; • Expected completion status: 0x20 (recalibrate successful)
  3329. ; • Status mask 0xF8: Checks upper 5 bits for error conditions
  3330. ;
  3331. ; Returns:
  3332. ; • Carry set: RECALIBRATE completed successfully, drive ready
  3333. ; • Carry clear: RECALIBRATE failed or timeout occurred
  3334. ;==============================================================================
  3335. l0b54h:
  3336. ld a,(0124ah) ;0b54 ; Read operation completion status
  3337. or a ;0b57 ; Test if operation completed (non-zero)
  3338. jr z,l0b54h ;0b58 ; Loop until completion flag is set
  3339. and 0f8h ;0b5a ; Mask upper 5 bits to check for errors
  3340. xor 020h ;0b5c ; Compare with expected success status (0x20)
  3341. ret nz ;0b5e ; Return with carry clear if not successful
  3342. ld (iy+000h),a ;0b5f ; Store final status (0x00) in drive status
  3343. scf ;0b62 ; Set carry flag (operation successful)
  3344. ret ;0b63 ; Return with success status
  3345. ;==============================================================================
  3346. ; FLOPPY CONTROLLER I/O TRANSMITTER (0x0B64)
  3347. ;==============================================================================
  3348. ; Purpose: Send command bytes to floppy controller via I/O ports
  3349. ; Input: HL = pointer to command buffer, B = byte count, C = 0xF1 (data port)
  3350. ;
  3351. ; Function:
  3352. ; - Waits for floppy controller ready (port 0xF0 status bits 0-4 clear)
  3353. ; - Polls bit 7 of status port 0xF0 for command ready signal
  3354. ; - Checks bit 6 for transfer direction/error condition
  3355. ; - Uses OUTI instruction to send bytes from buffer to port 0xF1
  3356. ; - Continues until all B bytes transmitted
  3357. ;
  3358. ; Ports Used:
  3359. ; - 0xF0: Floppy controller status register
  3360. ; - Bit 7: Command ready flag
  3361. ; - Bit 6: Direction/error flag
  3362. ; - Bits 0-4: Various status conditions
  3363. ; - 0xF1: Floppy controller data register (via register C)
  3364. ;
  3365. ; Returns: Carry set on success, clear on error
  3366. ;==============================================================================
  3367. l0b64h:
  3368. ld c,0f1h ;0b64 Set port C = 0xF1 (FDC data register)
  3369. l0b66h:
  3370. in a,(0f0h) ;0b66 Read FDC status register (port 0xF0)
  3371. and 01fh ;0b68 Mask lower 5 bits (status/error flags)
  3372. jr nz,l0b66h ;0b6a Loop until all status flags are clear
  3373. l0b6ch:
  3374. in a,(0f0h) ;0b6c Read FDC status register again
  3375. bit 7,a ;0b6e Test bit 7 (command ready flag)
  3376. jr z,l0b6ch ;0b70 Loop until FDC is ready for command
  3377. and 040h ;0b72 Test bit 6 (direction/error flag)
  3378. ret nz ;0b74 Return with error if direction flag set
  3379. outi ;0b75 Output byte from (HL) to port C, increment HL, decrement B
  3380. jr nz,l0b6ch ;0b77 Loop until all B bytes transmitted (B≠0)
  3381. scf ;0b79 Set carry flag = success (all bytes transmitted)
  3382. ret ;0b7a Return to caller with success status
  3383. ;==============================================================================
  3384. ; FLOPPY COMMAND PARAMETER BUILDER (0x0B7B)
  3385. ;==============================================================================
  3386. ; Purpose: Build drive and head selection parameters for floppy commands
  3387. ; Input: HL = pointer to command buffer (pointing to parameter byte location)
  3388. ;
  3389. ; Function:
  3390. ; - Reads drive selection from 0x1226, rotates left twice (bits 6-7 → bits 0-1)
  3391. ; - Combines with head selection from 0x1202
  3392. ; - Stores combined drive/head parameter in command buffer
  3393. ; - Advances buffer pointer for next parameter
  3394. ;
  3395. ; Parameter Format:
  3396. ; - Bits 0-1: Drive number (from 0x1226 bits 6-7)
  3397. ; - Other bits: Head selection and flags (from 0x1202)
  3398. ;
  3399. ; Memory Locations:
  3400. ; - 0x1226: Drive selection (bits 6-7 used)
  3401. ; - 0x1202: Head selection and other flags
  3402. ;==============================================================================
  3403. sub_0b7bh:
  3404. ld a,(01226h) ;0b7b
  3405. rlca ;0b7e
  3406. rlca ;0b7f
  3407. ld (hl),a ;0b80
  3408. ld a,(01202h) ;0b81
  3409. or (hl) ;0b84
  3410. ld (hl),a ;0b85
  3411. inc hl ;0b86
  3412. ret ;0b87
  3413. ;==============================================================================
  3414. ; FLOPPY CONTROLLER RESPONSE READER (0x0B88)
  3415. ;==============================================================================
  3416. ; Purpose: Read response bytes from floppy controller after command execution
  3417. ;
  3418. ; Function:
  3419. ; - Sets up response buffer at 0x121C
  3420. ; - Uses port 0xF1 for data input (via register C)
  3421. ; - Implements timeout loop (B=0x0A iterations)
  3422. ; - Polls port 0xF0 status register:
  3423. ; - Bit 4: Data ready flag
  3424. ; - Bit 7: Controller ready flag
  3425. ; - Bit 6: Direction/completion flag
  3426. ; - Uses INI instruction to read bytes from port 0xF1 to buffer
  3427. ; - Returns first response byte and sets carry on success
  3428. ;
  3429. ; Timeout Handling:
  3430. ; - 10-iteration outer loop for timeout protection
  3431. ; - Inner delay loop for timing control
  3432. ; - Returns with carry clear on timeout
  3433. ;
  3434. ; Returns: A = first response byte, Carry = success flag
  3435. ;==============================================================================
  3436. l0b88h:
  3437. ld hl,0121ch ;0b88
  3438. ld c,0f1h ;0b8b
  3439. l0b8dh:
  3440. ld b,00ah ;0b8d
  3441. l0b8fh:
  3442. djnz l0b8fh ;0b8f
  3443. l0b91h:
  3444. in a,(0f0h) ;0b91
  3445. bit 4,a ;0b93
  3446. jr z,l0ba2h ;0b95
  3447. bit 7,a ;0b97
  3448. jr z,l0b91h ;0b99
  3449. and 040h ;0b9b
  3450. ret z ;0b9d
  3451. ini ;0b9e
  3452. jr l0b8dh ;0ba0
  3453. l0ba2h:
  3454. ld a,(0121ch) ;0ba2
  3455. scf ;0ba5
  3456. ret ;0ba6
  3457. sub_0ba7h:
  3458. ld hl,01213h ;0ba7
  3459. ld (hl),008h ;0baa
  3460. ld bc,001f1h ;0bac
  3461. call l0b6ch ;0baf
  3462. ret nc ;0bb2
  3463. jp l0b88h ;0bb3
  3464. l0bb6h:
  3465. push af ;0bb6
  3466. push hl ;0bb7
  3467. push bc ;0bb8
  3468. push de ;0bb9
  3469. l0bbah:
  3470. in a,(0f0h) ;0bba ; Read floppy controller main status register
  3471. bit 7,a ;0bbc ; Test READY bit (controller ready)
  3472. jr z,l0bbah ;0bbe ; Wait until controller is ready
  3473. bit 6,a ;0bc0 ; Test DATA_REQUEST bit (controller needs data)
  3474. jr z,l0bd9h ;0bc2 ; If no data request, handle differently
  3475. ld a,083h ;0bc4 ; Load DMA command 0x83
  3476. out (0fch),a ;0bc6 ; Send command to Z80 DMA controller port 0xFC
  3477. ; ; 0x83 = DMA control command for FDC coordination
  3478. ld (0124bh),a ;0bc8
  3479. call l0b88h ;0bcb
  3480. ld hl,0121ch ;0bce
  3481. ld de,0120ch ;0bd1
  3482. ld bc,00007h ;0bd4
  3483. ldir ;0bd7
  3484. l0bd9h:
  3485. call sub_0ba7h ;0bd9
  3486. jr nc,l0bebh ;0bdc
  3487. cp 080h ;0bde
  3488. jr z,l0bebh ;0be0
  3489. bit 5,a ;0be2
  3490. jr z,l0bd9h ;0be4
  3491. ld (0124ah),a ;0be6
  3492. jr l0bd9h ;0be9
  3493. l0bebh:
  3494. pop de ;0beb
  3495. pop bc ;0bec
  3496. pop hl ;0bed
  3497. pop af ;0bee
  3498. ei ;0bef
  3499. reti ;0bf0
  3500. ;==============================================================================
  3501. ; FLOPPY DISK CONTROLLER WRITE COMMAND SETUP (sub_0bf2h) - 0x0BF2-0x0C04
  3502. ;==============================================================================
  3503. ; Purpose: Configure NEC µPD765A FDC for WRITE DATA operations (command 0x04)
  3504. ; Called by: W command (0x09FA), sub_0d2eh (R command), and other disk routines
  3505. ;
  3506. ; CRITICAL FUNCTION: This routine sets up the FDC command 0x04 (WRITE DATA)
  3507. ; and prepares the controller for disk write operations using parameters
  3508. ; previously configured by the O command.
  3509. ;
  3510. ; INPUT CONTEXT:
  3511. ; - O command has configured: drive (0x1202), track (0x1225), sectors (0x1227)
  3512. ; - Calling command (W/R) provides: memory address, data length
  3513. ; - FDC command buffer at 0x1213-0x1215 ready for command setup
  3514. ;
  3515. ; OPERATION SEQUENCE:
  3516. ; 1. Set up command buffer with WRITE DATA command (0x04)
  3517. ; 2. Add drive/head parameters via sub_0b7bh
  3518. ; 3. Transmit command to FDC via ports 0xF0/0xF1
  3519. ; 4. Return status for caller processing
  3520. ;
  3521. ; FDC COMMAND 0x04: WRITE DATA - Writes sector data to floppy disk
  3522. ; Buffer Layout: [0x1213]=0x04, [0x1214]=drive/head, [0x1215]=track
  3523. ;
  3524. ; HARDWARE INTERFACE:
  3525. ; - Port 0xF0: FDC main status register (ready/busy status)
  3526. ; - Port 0xF1: FDC data register (command and parameter transfer)
  3527. ; - Memory 0x1213-0x1215: Command parameter block
  3528. ;
  3529. ; RETURNS: Status in accumulator, carry flag indicates success/failure
  3530. ;==============================================================================
  3531. sub_0bf2h:
  3532. ld hl,01213h ;0bf2 Point to FDC command buffer (command parameter block)
  3533. push hl ;0bf5 Save buffer pointer for later restoration
  3534. ld (hl),004h ;0bf6 Set FDC command = 0x04 (WRITE DATA command)
  3535. inc hl ;0bf8 Move to next buffer position (0x1214)
  3536. call sub_0b7bh ;0bf9 Add drive/head parameters from O command config
  3537. pop hl ;0bfc Restore command buffer pointer to start (0x1213)
  3538. ld b,002h ;0bfd Set parameter count = 2 bytes (command + drive/head)
  3539. call l0b64h ;0bff Transmit command buffer to FDC via port 0xF1
  3540. jp l0b88h ;0c02 Jump to FDC response handler and return status
  3541. ; End sub_0bf2h: Command 0x04 configured and sent, response processing in l0b88h
  3542. ;==============================================================================
  3543. ;==============================================================================
  3544. ; DISK SEEK AND STATUS CHECK ROUTINE (sub_0c05h) - 0x0C05-0x0C2E
  3545. ;==============================================================================
  3546. ; Purpose: Execute SEEK command (0x0F) to position disk head on specified track
  3547. ; Called by: Various disk operations that need head positioning before I/O
  3548. ;
  3549. ; OPERATION SEQUENCE:
  3550. ; 1. Verify write capability by calling sub_0d2eh (WRITE command validation)
  3551. ; 2. If write OK, execute SEEK command (0x0F) to position head on track
  3552. ; 3. Wait for seek completion and verify positioning status
  3553. ;
  3554. ; CRITICAL FUNCTION: This ensures the disk head is properly positioned before
  3555. ; read/write operations, using the track number configured by O command.
  3556. ;
  3557. ; INPUT REQUIREMENTS:
  3558. ; - Track number at 0x1225 (configured by O command)
  3559. ; - Drive/head parameters at 0x1226, 0x1202 (from O command)
  3560. ; - FDC must be ready for command execution
  3561. ;
  3562. ; FDC COMMAND 0x0F: SEEK - Positions disk head to specified track/cylinder
  3563. ; Buffer Layout: [0x1213]=0x0F, [0x1214]=drive/head, [0x1215]=track
  3564. ;
  3565. ; RETURNS: Carry set on success, clear on failure
  3566. ;==============================================================================
  3567. sub_0c05h:
  3568. call sub_0d2eh ;0c05 Test write capability (validates FDC write readiness)
  3569. ret nc ;0c08 Return if write validation failed (no seek possible)
  3570. ld hl,01213h ;0c09 Point to FDC command buffer for SEEK command setup
  3571. push hl ;0c0c Save command buffer pointer for later restoration
  3572. ld (hl),00fh ;0c0d Set FDC command = 0x0F (SEEK command)
  3573. inc hl ;0c0f Move to parameter position (0x1214)
  3574. call sub_0b7bh ;0c10 Add drive/head parameters from O command configuration
  3575. ld a,(01225h) ;0c13 Load target track number (configured by O command)
  3576. ld (hl),a ;0c16 Store track number in command buffer (0x1215)
  3577. xor a ;0c17 Clear accumulator (A = 0)
  3578. ld (0124ah),a ;0c18 Clear seek completion status flag
  3579. pop hl ;0c1b Restore command buffer pointer to start (0x1213)
  3580. ld b,003h ;0c1c Set parameter count = 3 bytes (cmd + drive/head + track)
  3581. call l0b64h ;0c1e Transmit SEEK command to FDC via port 0xF1
  3582. ret nc ;0c21 Return if command transmission failed
  3583. l0c22h:
  3584. ; SEEK COMPLETION WAIT LOOP - Monitor FDC status for seek operation completion
  3585. ld a,(0124ah) ;0c22 Check seek completion status flag
  3586. or a ;0c25 Test if status has been updated (non-zero = complete)
  3587. jr z,l0c22h ;0c26 Loop until seek operation completes
  3588. and 0f8h ;0c28 Mask status bits: check for error conditions (bits 3-7)
  3589. xor 020h ;0c2a XOR with 0x20: test for expected completion status
  3590. ret nz ;0c2c Return with error if status doesn't match expected
  3591. scf ;0c2d Set carry flag = success (seek completed successfully)
  3592. ret ;0c2e Return to caller with success status
  3593. ; End sub_0c05h: SEEK command completed, head positioned on target track
  3594. ;==============================================================================
  3595. ; DISK I/O OPERATION DISPATCH ROUTINE (l0c2fh/l0c33h) - 0x0C2F-0x0C69
  3596. ;==============================================================================
  3597. ; Purpose: High-level disk I/O operation coordinator with dual entry points
  3598. ; Entry Points:
  3599. ; l0c2fh: Entry for write operations (sets operation type = 6)
  3600. ; l0c33h: Entry for read operations (sets operation type = 5)
  3601. ; Called by: Disk I/O functions requiring complete read/write operation sequence
  3602. ;
  3603. ; Operation Sequence:
  3604. ; 1. Set operation type (read=5, write=6) in memory location 0x1223
  3605. ; 2. Check drive configuration status and exit if not configured
  3606. ; 3. Configure drive parameters, FDC commands, and DMA setup
  3607. ; 4. Execute FDC operation with up to 9 retry attempts
  3608. ; 5. Perform final status validation and error checking
  3609. ; 6. Return with success/failure status
  3610. ;
  3611. ; Returns: Carry flag set = success, clear = failure
  3612. ; Memory: Uses 0x1223 for operation type, 0x124B for error status
  3613. ;==============================================================================
  3614. l0c2fh:
  3615. ld a,006h ;0c2f Set operation type = 6 (WRITE operation)
  3616. jr l0c35h ;0c31 Jump to common I/O processing
  3617. l0c33h:
  3618. ld a,005h ;0c33 Set operation type = 5 (READ operation)
  3619. l0c35h:
  3620. ld hl,01223h ;0c35 Point to operation type storage location
  3621. ld (hl),a ;0c38 Store operation type (5 or 6) in memory
  3622. ld a,(01204h) ;0c39 Load drive configuration byte from memory
  3623. or a ;0c3c Test if drive is configured (non-zero = configured)
  3624. ret nz ;0c3d Return immediately if drive not configured
  3625. call sub_0c6ah ;0c3e Call drive configuration setup routine
  3626. call sub_0b7bh ;0c41 Call FDC command preparation routine
  3627. call sub_0c73h ;0c44 Call DMA parameter configuration routine
  3628. call sub_0d2eh ;0c47 Call FDC status validation routine
  3629. ret nc ;0c4a Return with error if FDC validation failed
  3630. call sub_0ca0h ;0c4b Call FDC operation setup routine
  3631. call sub_0cc5h ;0c4e Call DMA transfer configuration routine
  3632. xor a ;0c51 Clear accumulator (A = 0)
  3633. ld (0124bh),a ;0c52 Clear error status flag in memory
  3634. ld hl,01223h ;0c55 Point to operation type location
  3635. ld b,009h ;0c58 Set retry count = 9 attempts
  3636. call l0b64h ;0c5a Call FDC command execution routine
  3637. ret nc ;0c5d Return with error if command execution failed
  3638. call sub_0d11h ;0c5e Call final status check routine
  3639. ret nc ;0c61 Return with error if final status check failed
  3640. ld a,(0120ch) ;0c62 Load final operation status byte
  3641. and 0c0h ;0c65 Mask upper 2 bits (critical error flags)
  3642. ret nz ;0c67 Return with error if critical errors detected
  3643. scf ;0c68 Set carry flag = success (operation completed)
  3644. ret ;0c69 Return to caller with success status
  3645. sub_0c6ah:
  3646. ld a,(01203h) ;0c6a
  3647. rrca ;0c6d
  3648. rrca ;0c6e
  3649. or (hl) ;0c6f
  3650. ld (hl),a ;0c70
  3651. inc hl ;0c71
  3652. ret ;0c72
  3653. sub_0c73h:
  3654. ld hl,l0c90h ;0c73
  3655. ld de,01228h ;0c76
  3656. jr l0c81h ;0c79
  3657. sub_0c7bh:
  3658. ld hl,l0c98h ;0c7b
  3659. ld de,01215h ;0c7e
  3660. l0c81h:
  3661. ld a,(01203h) ;0c81
  3662. add a,a ;0c84
  3663. add a,a ;0c85
  3664. ld c,a ;0c86
  3665. ld b,000h ;0c87
  3666. add hl,bc ;0c89
  3667. ld bc,00004h ;0c8a Set copy length = 4 bytes (copy 4 bytes of lookup data)
  3668. ldir ;0c8d Copy data block: HL→DE for BC bytes (data table copy)
  3669. ret ;0c8f Return after data table has been copied to target location
  3670. ;==============================================================================
  3671. ; DISK PARAMETER LOOKUP TABLE 1 (l0c90h) - 0x0C90-0x0C97
  3672. ;==============================================================================
  3673. ; Purpose: Disk operation parameter lookup table for drive configuration
  3674. ; Usage: Referenced by sub_0c73h, copied to memory location 0x1228+
  3675. ; Format: 8-byte data table containing disk controller configuration values
  3676. ;==============================================================================
  3677. l0c90h:
  3678. defb 000h ;0c90 Parameter byte 0: Base configuration value
  3679. defb 01ah ;0c91 Parameter byte 1: Drive timing/control setting
  3680. defb 020h ;0c92 Parameter byte 2: Drive mode flags
  3681. defb 080h ;0c93 Parameter byte 3: Drive status/control flags
  3682. defb 01ah, 00eh ;0c94 Parameter bytes 4-5: Extended configuration (0x0E1A)
  3683. defb 0ffh ;0c96 Parameter byte 6: End marker/control flag
  3684. defb 000h ;0c97 Parameter byte 7: Padding/reserved
  3685. ;==============================================================================
  3686. ; DISK PARAMETER LOOKUP TABLE 2 (l0c98h) - 0x0C98-0x0C9F
  3687. ;==============================================================================
  3688. ; Purpose: Alternate disk operation parameter table for different operations
  3689. ; Usage: Referenced by sub_0c7bh, copied to memory location 0x1215+
  3690. ; Format: 8-byte data table for alternate disk controller configuration
  3691. ;==============================================================================
  3692. l0c98h:
  3693. defb 000h ;0c98 Parameter byte 0: Alternate base configuration
  3694. defb 01ah ;0c99 Parameter byte 1: Alternate timing setting
  3695. defb 0edh ;0c9a Parameter byte 2: Alternate mode flags
  3696. defb 0e5h ;0c9b Parameter byte 3: Alternate control settings
  3697. defb 01ah, 036h ;0c9c Parameter bytes 4-5: Extended alternate config (0x361A)
  3698. defb 0e5h ;0c9e Parameter byte 6: Alternate end marker
  3699. defb 000h ;0c9f Parameter byte 7: Alternate padding/reserved
  3700. ;==============================================================================
  3701. ; Z80 DMA CONTROLLER CONFIGURATION ROUTINE (sub_0ca0h) - 0x0CA0-0x0CBC
  3702. ;==============================================================================
  3703. ; Purpose: Configure Z80 DMA controller for disk data transfer operations
  3704. ; Called by: Disk I/O routines that need DMA setup for high-speed transfers
  3705. ;
  3706. ; OPERATION: Sets up DMA channel parameters for floppy disk data transfers
  3707. ; This routine configures the Z80 DMA controller to handle high-speed data
  3708. ; movement between the floppy disk controller and system memory.
  3709. ;
  3710. ; DMA CONFIGURATION SEQUENCE:
  3711. ; 1. Calculate DMA parameters based on drive status and transfer requirements
  3712. ; 2. Send WR1 register setup (0x47) with drive-specific parameters
  3713. ; 3. Send WR3 register setup (0x57) with transfer control parameters
  3714. ;
  3715. ; HARDWARE INTERFACE:
  3716. ; - Port 0xF4: Z80 DMA WR1 register (memory address and count setup)
  3717. ; - Port 0xF5: Z80 DMA WR3 register (transfer mode and control)
  3718. ; - Memory 0x1203: Drive status flags (used for DMA parameter calculation)
  3719. ;
  3720. ; PARAMETERS:
  3721. ; - D register: Drive-specific DMA configuration value
  3722. ; - E register: Transfer mode and control settings
  3723. ;==============================================================================
  3724. sub_0ca0h:
  3725. ld a,(01203h) ;0ca0 Load drive status flags from system configuration
  3726. inc a ;0ca3 Increment for DMA calculation (A = drive_status + 1)
  3727. ld d,a ;0ca4 Store calculated drive parameter in D register
  3728. ld e,080h ;0ca5 Set transfer control mode = 0x80 (DMA mode flags)
  3729. jr l0cadh ;0ca7 Jump to common DMA configuration routine
  3730. ;==============================================================================
  3731. ; ALTERNATE DMA CONFIGURATION ENTRY POINT (sub_0ca9h) - 0x0CA9-0x0CAC
  3732. ;==============================================================================
  3733. ; Purpose: Alternative DMA setup with fixed parameters for specific operations
  3734. ; Used for: Standard disk operations with preset DMA configuration
  3735. ;==============================================================================
  3736. sub_0ca9h:
  3737. ld d,001h ;0ca9 Set fixed drive parameter = 0x01 (standard mode)
  3738. ld e,068h ;0cab Set fixed transfer control = 0x68 (alternate mode)
  3739. ;==============================================================================
  3740. ; COMMON DMA REGISTER CONFIGURATION (l0cadh) - 0x0CAD-0x0CBC
  3741. ;==============================================================================
  3742. ; Purpose: Send DMA configuration commands to Z80 DMA controller
  3743. ; Input: D = drive/address parameter, E = transfer control parameter
  3744. ;
  3745. ; Z80 DMA PROGRAMMING SEQUENCE:
  3746. ; Command 0x47: WR1 register - Memory address and byte count configuration
  3747. ; Command 0x57: WR3 register - Transfer mode, timing, and control settings
  3748. ;
  3749. ; The Z80 DMA controller requires specific command sequences to configure
  3750. ; memory-to-peripheral transfers for high-speed floppy disk operations.
  3751. ;==============================================================================
  3752. l0cadh:
  3753. ld c,0f4h ;0cad Set port address = 0xF4 (Z80 DMA WR1 register)
  3754. ld a,047h ;0caf Load DMA command = 0x47 (WR1: address/count setup)
  3755. out (c),a ;0cb1 Send WR1 command to DMA controller
  3756. out (c),d ;0cb3 Send drive/address parameter to DMA WR1 register
  3757. inc c ;0cb5 Move to next DMA port = 0xF5 (WR3 register)
  3758. ld a,057h ;0cb6 Load DMA command = 0x57 (WR3: transfer mode setup)
  3759. out (c),a ;0cb8 Send WR3 command to DMA controller
  3760. out (c),e ;0cba Send transfer control parameter to DMA WR3 register
  3761. ret ;0cbc Return to caller with DMA controller configured
  3762. ; End DMA configuration: Z80 DMA ready for high-speed disk data transfers
  3763. ;==============================================================================
  3764. ; DMA TRANSFER LENGTH SETUP ROUTINE (sub_0cbdh) - 0x0CBD-0x0CFA
  3765. ;==============================================================================
  3766. ; Purpose: Configure DMA transfer parameters and initiate disk data transfer
  3767. ; Called by: Format and disk I/O operations requiring DMA data movement
  3768. ;
  3769. ; Operation:
  3770. ; 1. Calculate transfer length based on operation type and FDC command
  3771. ; 2. Set up DMA configuration block from ROM template
  3772. ; 3. Configure memory addresses and transfer parameters
  3773. ; 4. Send complete DMA configuration to Z80 DMA controller
  3774. ;
  3775. ; Transfer Types: Different lengths for read/write vs format operations
  3776. ; Memory: Uses 0x122C as DMA configuration workspace, ports 0xFC for DMA
  3777. ;==============================================================================
  3778. sub_0cbdh:
  3779. ld hl,00068h ;0cbd Set default transfer length to 0x68 (104 bytes)
  3780. ld a,(01213h) ;0cc0 Load FDC command byte from command buffer
  3781. jr l0cd2h ;0cc3 Jump to common DMA setup processing
  3782. sub_0cc5h:
  3783. ld hl,l0080h ;0cc5 Set base transfer length to 0x80 (128 bytes)
  3784. ld a,(01203h) ;0cc8 Load drive status/configuration byte
  3785. or a ;0ccb Test if drive supports extended operations
  3786. jr z,l0ccfh ;0ccc Skip length doubling if standard operation
  3787. add hl,hl ;0cce Double transfer length (0x80 → 0x100 = 256 bytes)
  3788. l0ccfh:
  3789. ld a,(01223h) ;0ccf Load disk operation parameter for processing
  3790. l0cd2h:
  3791. dec hl ;0cd2 Decrement transfer length (adjust for DMA requirements)
  3792. push hl ;0cd3 Save adjusted transfer length on stack
  3793. ld hl,l0cfbh ;0cd4 Point to DMA configuration template in ROM
  3794. ld de,0122ch ;0cd7 Point to DMA configuration workspace in RAM
  3795. ld bc,00016h ;0cda Set copy length to 22 bytes (0x16)
  3796. ldir ;0cdd Copy DMA template from ROM to RAM workspace
  3797. pop hl ;0cdf Restore transfer length from stack
  3798. ld (01235h),hl ;0ce0 Store transfer length in DMA block (bytes 8-9)
  3799. ld hl,(01200h) ;0ce3 Load DMA buffer address from memory
  3800. ld (01233h),hl ;0ce6 Store buffer address in DMA block (bytes 6-7)
  3801. and 001h ;0ce9 Test bit 0 of operation parameter (direction flag)
  3802. rlca ;0ceb Rotate left (bit 0 → bit 1)
  3803. rlca ;0cec Rotate left (bit 1 → bit 2, final position)
  3804. ld hl,0123eh ;0ced Point to DMA control byte in configuration block
  3805. or (hl) ;0cf0 OR with existing control settings
  3806. ld (hl),a ;0cf1 Store updated control byte with direction flag
  3807. ld hl,0122ch ;0cf2 Point to start of DMA configuration block
  3808. ld bc,016fch ;0cf5 Set B=22 (bytes to send), C=0xFC (DMA port)
  3809. otir ;0cf8 Send 22-byte DMA configuration to Z80 DMA controller
  3810. ret ;0cfa Return with DMA controller configured and ready
  3811. ;==============================================================================
  3812. ; DMA CONFIGURATION DATA BLOCK (l0cfbh) - 0x0CFB-0x0D10 (22 bytes)
  3813. ;==============================================================================
  3814. ; Purpose: 22-byte DMA configuration data block copied to RAM at 0x122C
  3815. ; Usage: Referenced by routine at 0cd7h, copied via BC=0016h + LDIR
  3816. ;==============================================================================
  3817. l0cfbh:
  3818. defb 0c3h ;0cfb DMA WR0: Base register - Enable DMA, memory-to-I/O transfer
  3819. defb 0c3h ;0cfc DMA WR1: Port A address low byte (or timing control)
  3820. defb 0c3h ;0cfd DMA WR1: Port A address high byte
  3821. defb 0c3h ;0cfe DMA WR2: Block length low byte (or port config)
  3822. defb 0c3h ;0cff DMA WR2: Block length high byte
  3823. defb 0c3h ;0d00 DMA WR3: Port A timing and control settings
  3824. defb 079h ;0d01 DMA WR4: Port B configuration (0x79 = I/O port mode)
  3825. defb 000h ;0d02 DMA WR5: Port B address low byte (0x00)
  3826. defb 000h ;0d03 DMA WR5: Port B address high byte (0x00)
  3827. defb 000h ;0d04 DMA WR6: Port B timing control (0x00 = default)
  3828. defb 000h ;0d05 Reserved/padding byte for alignment
  3829. defb 014h ;0d06 DMA command: Load (0x14 = Load WR4 command)
  3830. defb 028h ;0d07 DMA timing: Cycle length configuration
  3831. defb 089h ;0d08 DMA control: Transfer mode and direction flags
  3832. defb 0f2h ;0d09 DMA status: Ready/enable flags (0xF2)
  3833. defb 082h ;0d0a DMA port config: FDC data register selection
  3834. defb 083h ;0d0b DMA command: Enable/start transfer (0x83)
  3835. defb 0cfh ;0d0c DMA interrupt: Vector and control (0xCF)
  3836. defb 001h ;0d0d DMA counter: Transfer count low byte
  3837. defb 083h ;0d0e DMA control: Final command byte (0x83)
  3838. defb 0cfh ;0d0f DMA vector: Interrupt vector high byte
  3839. defb 007h ;0d10 DMA mask: End-of-block mask/control (final config byte)
  3840. ;==============================================================================
  3841. ; DISK OPERATION STATUS POLLING ROUTINE (sub_0d11h) - 0x0D11-0x0D2D
  3842. ;==============================================================================
  3843. ; Purpose: Wait for disk operation completion by polling status register
  3844. ; Called by: Disk I/O routines that need to wait for operation completion
  3845. ;
  3846. ; Operation:
  3847. ; 1. Initialize BC=0x0000 (timeout counter: B=0, C=0 = 65536 iterations max)
  3848. ; 2. Poll status location 0x124B repeatedly until non-zero (operation done)
  3849. ; 3. If status becomes non-zero, set carry flag and return (success)
  3850. ; 4. If timeout expires, send DMA command 0x83 and call FDC init
  3851. ; 5. Clear carry flag and return (timeout/error)
  3852. ;
  3853. ; Memory: 0x124B = FDC operation status (0=busy, non-zero=complete)
  3854. ; Ports: 0xFC = Z80 DMA controller command port
  3855. ;==============================================================================
  3856. sub_0d11h:
  3857. ld bc,l0000h ;0d11 Initialize timeout counter (BC=0x0000 = 65536 max loops)
  3858. l0d14h: ; Status polling loop entry point
  3859. ld a,(0124bh) ;0d14 Load FDC operation status from memory
  3860. or a ;0d17 Test if status is non-zero (operation complete)
  3861. scf ;0d18 Set carry flag (success indicator)
  3862. ret nz ;0d19 Return with carry set if operation completed
  3863. ld a,(0124bh) ;0d1a Load status again (double-check for reliability)
  3864. or a ;0d1d Test status again
  3865. scf ;0d1e Set carry flag again
  3866. ret nz ;0d1f Return with carry if now complete
  3867. djnz l0d14h ;0d20 Decrement B counter, loop if not zero
  3868. dec c ;0d22 Decrement C counter (outer loop)
  3869. jr nz,l0d14h ;0d23 Continue polling if C not zero (timeout not reached)
  3870. ld a,083h ;0d25 Load DMA command 0x83 (timeout cleanup)
  3871. out (0fch),a ;0d27 Send command to Z80 DMA controller port 0xFC
  3872. ; 0x83 = DMA control command for disk operations
  3873. call sub_0a8dh ;0d29 Call FDC initialization routine (recovery attempt)
  3874. or a ;0d2c Clear carry flag (indicate timeout/error)
  3875. ret ;0d2d Return with carry clear (failure)
  3876. ;==============================================================================
  3877. ; FDC WRITE STATUS CHECK ROUTINE (sub_0d2eh) - 0x0D2E-0x0D36
  3878. ;==============================================================================
  3879. ; Purpose: Check if FDC is ready for write operations by testing status bit 5
  3880. ; Called by: Write command routines and disk operation validators
  3881. ;
  3882. ; Operation:
  3883. ; 1. Call sub_0bf2h (FDC write command setup) to get current FDC status
  3884. ; 2. Return with carry clear if FDC setup failed (not ready)
  3885. ; 3. Test bit 5 of status register (write ready indicator)
  3886. ; 4. Return with carry clear if bit 5 is zero (write not ready)
  3887. ; 5. Return with carry set if bit 5 is set (write ready)
  3888. ;
  3889. ; Returns: Carry flag = FDC write ready status (1=ready, 0=not ready)
  3890. ;==============================================================================
  3891. sub_0d2eh:
  3892. call sub_0bf2h ;0d2e Call FDC write command setup, get status in A
  3893. ret nc ;0d31 Return with carry clear if FDC setup failed
  3894. and 020h ;0d32 Test bit 5 of status (write ready indicator)
  3895. ret z ;0d34 Return with carry clear if bit 5 = 0 (not ready)
  3896. scf ;0d35 Set carry flag (write ready confirmed)
  3897. ret ;0d36
  3898. ;==============================================================================
  3899. ; DISK SEEK AND RETRY OPERATION (sub_0d37h) - 0x0D37-0x0D59
  3900. ;==============================================================================
  3901. ; Purpose: Perform disk seek operation with retry logic and status tracking
  3902. ; Called by: Disk operation routines that need head positioning and validation
  3903. ;
  3904. ; Operation:
  3905. ; 1. Check if FDC is ready for write operations (via sub_0d2eh)
  3906. ; 2. If not ready, return with carry clear (failure)
  3907. ; 3. Set retry counter to 2 attempts (B=0x02)
  3908. ; 4. For each attempt:
  3909. ; - Call sub_0c05h (disk seek and status check)
  3910. ; - Store current track number from 0x1225 to IY+0 (drive status table)
  3911. ; - If seek successful (carry set), return immediately
  3912. ; - Call sub_0b1ch (disk read operation)
  3913. ; - If read fails, return with carry clear
  3914. ; - Increment error counter at 0x1244
  3915. ; - Retry if attempts remaining
  3916. ; 5. Clear carry and return if all retries exhausted
  3917. ;
  3918. ; Memory: 0x1225=track number, 0x1244=error counter, IY=drive status pointer
  3919. ;==============================================================================
  3920. sub_0d37h:
  3921. call sub_0d2eh ;0d37 Check if FDC is ready for write operations
  3922. ret nc ;0d3a Return with carry clear if FDC not ready
  3923. ld b,002h ;0d3b Set retry counter to 2 attempts
  3924. l0d3dh: ; Retry loop entry point
  3925. push bc ;0d3d Save retry counter on stack
  3926. call sub_0c05h ;0d3e Call disk seek and status check routine
  3927. pop bc ;0d41 Restore retry counter from stack
  3928. ld a,(01225h) ;0d42 Load current track number from memory
  3929. ld (iy+000h),a ;0d45 Store track number in drive status table (IY+0)
  3930. ret c ;0d48 Return with carry set if seek was successful
  3931. push bc ;0d49 Save retry counter again
  3932. call sub_0b1ch ;0d4a Call disk read operation to verify positioning
  3933. pop bc ;0d4d Restore retry counter
  3934. ret nc ;0d4e Return with carry clear if read operation failed
  3935. ld hl,(01244h) ;0d4f Load error counter from memory location 0x1244
  3936. inc hl ;0d52 Increment error counter (track retry attempt)
  3937. ld (01244h),hl ;0d53 Store updated error counter back to memory
  3938. djnz l0d3dh ;0d56 Decrement retry counter, loop if more attempts remain
  3939. or a ;0d58 Clear carry flag (all retries exhausted, operation failed)
  3940. ret ;0d59 Return with carry clear indicating failure
  3941. ;==============================================================================
  3942. ; FDC STATUS VALIDATION ROUTINE (l0d5ah) - 0x0D5A-0x0D66
  3943. ;==============================================================================
  3944. ; Purpose: Validate FDC status bits for specific disk operation conditions
  3945. ; Called by: Disk operation routines that need to check controller readiness
  3946. ;
  3947. ; Operation:
  3948. ; 1. Call sub_0bf2h to get current FDC status byte
  3949. ; 2. XOR with 0x20 (flip bit 5 - write ready indicator)
  3950. ; 3. AND with 0x60 (test bits 5&6 - data direction and write ready)
  3951. ; 4. Return with non-zero flag if status invalid (operation not ready)
  3952. ; 5. If status valid, load parameter table pointer and continue
  3953. ;
  3954. ; Status Bits: Bit 5=write ready, Bit 6=data direction
  3955. ; Memory: 0x120D=FDC status register (NOTE: Missing from main memory map)
  3956. ; Returns: Zero flag set=valid status, Zero flag clear=invalid status
  3957. ;==============================================================================
  3958. l0d5ah:
  3959. call sub_0bf2h ;0d5a Call FDC write setup, get status byte in A
  3960. xor 020h ;0d5d XOR with 0x20 (flip bit 5 - write ready bit)
  3961. and 060h ;0d5f AND with 0x60 (test bits 5&6 - data direction & write ready)
  3962. ret nz ;0d61 Return with non-zero if status invalid (not ready)
  3963. ld hl,l0c33h ;0d62 Load pointer to disk parameter table (valid status)
  3964. jr l0d6eh ;0d65 Jump to common parameter processing routine
  3965. ;==============================================================================
  3966. ; ALTERNATE FDC VALIDATION ENTRY POINT (l0d67h) - 0x0D67-0x0D6D
  3967. ;==============================================================================
  3968. ; Purpose: Alternative entry point for FDC validation with different table
  3969. ; Operation: Checks write readiness then uses alternate parameter table
  3970. ;==============================================================================
  3971. l0d67h:
  3972. call sub_0d2eh ;0d67 Check if FDC is ready for write operations
  3973. ret nc ;0d6a Return with carry clear if FDC not ready
  3974. ld hl,l0c2fh ;0d6b Load pointer to alternate disk parameter table
  3975. ;==============================================================================
  3976. ; COMMON PARAMETER PROCESSING (l0d6eh) - 0x0D6E+
  3977. ;==============================================================================
  3978. ; Purpose: Common routine for processing disk parameters with retry logic
  3979. ; Input: HL = pointer to parameter table (l0c33h or l0c2fh)
  3980. ;==============================================================================
  3981. l0d6eh:
  3982. ld b,005h ;0d6e Set retry counter to 5 attempts
  3983. l0d70h: ; Main retry loop entry point
  3984. push bc ;0d70 Save retry counter on stack
  3985. push hl ;0d71 Save parameter table pointer on stack
  3986. call sub_0da8h ;0d72 Call parameter table function via HL register
  3987. pop hl ;0d75 Restore parameter table pointer from stack
  3988. pop bc ;0d76 Restore retry counter from stack
  3989. ret c ;0d77 Return with carry set if operation successful
  3990. push hl ;0d78 Save parameter table pointer again
  3991. ld a,(0120dh) ;0d79 Load FDC status register (error condition flags)
  3992. and 085h ;0d7c Test bits 0,2,7 (specific error conditions)
  3993. jr z,l0d87h ;0d7e Skip error counter increment if no error
  3994. ld hl,(01246h) ;0d80 Load error counter A from memory
  3995. inc hl ;0d83 Increment error counter A
  3996. ld (01246h),hl ;0d84 Store updated error counter A back to memory
  3997. l0d87h: ; Check additional error conditions
  3998. ld a,(0120dh) ;0d87 Load FDC status register again
  3999. and 020h ;0d8a Test bit 5 (write ready/direction error)
  4000. jr z,l0d95h ;0d8c Skip error counter B if bit 5 clear
  4001. ld hl,(01248h) ;0d8e Load error counter B from memory
  4002. inc hl ;0d91 Increment error counter B
  4003. ld (01248h),hl ;0d92 Store updated error counter B back to memory
  4004. l0d95h: ; Check extended error conditions
  4005. ld a,(0120eh) ;0d95 Load FDC extended status register
  4006. and 012h ;0d98 Test bits 1,4 (additional error flags)
  4007. jr z,l0da3h ;0d9a Skip general error counter if no error
  4008. ld hl,(01244h) ;0d9c Load general error counter from memory
  4009. inc hl ;0d9f Increment general error counter
  4010. ld (01244h),hl ;0da0 Store updated general error counter back to memory
  4011. l0da3h: ; End of retry loop
  4012. pop hl ;0da3 Restore parameter table pointer from stack
  4013. djnz l0d70h ;0da4 Decrement retry counter, loop if more attempts remain
  4014. or a ;0da6 Clear carry flag (all retries exhausted, operation failed)
  4015. ret ;0da7 Return with carry clear indicating failure
  4016. ;==============================================================================
  4017. ; INDIRECT FUNCTION CALL ROUTINES (0x0DA8-0x0DA9)
  4018. ;==============================================================================
  4019. ; Purpose: Dynamic function dispatching via register indirect calls
  4020. ; Used by: Parameter processing routines for flexible operation selection
  4021. ;==============================================================================
  4022. sub_0da8h:
  4023. jp (hl) ;0da8 Jump to address stored in HL register (parameter table function)
  4024. sub_0da9h:
  4025. jp (ix) ;0da9 Jump to address stored in IX register (operation function)
  4026. ;==============================================================================
  4027. ; DISK READ OPERATION ENTRY POINTS (l0dabh/l0db1h) - 0x0DAB-0x0DDF
  4028. ;==============================================================================
  4029. ; Purpose: High-level disk read operations with different validation approaches
  4030. ; Two entry points using different FDC validation routines:
  4031. ; - l0dabh: Uses l0d67h validation (write readiness check)
  4032. ; - l0db1h: Uses l0d5ah validation (status bit manipulation)
  4033. ;==============================================================================
  4034. l0dabh: ; Read operation entry point A
  4035. ld ix,l0d67h ;0dab Set IX to point to FDC validation routine (write check)
  4036. jr l0db5h ;0daf Jump to common read operation setup
  4037. l0db1h: ; Read operation entry point B
  4038. ld ix,l0d5ah ;0db1 Set IX to point to FDC validation routine (status bits)
  4039. l0db5h: ; Common read operation setup
  4040. ld iy,01205h ;0db5 Point IY to drive status table base address
  4041. ld b,002h ;0db9 Set operation retry counter to 2 attempts
  4042. ld a,(01202h) ;0dbb Load current drive number from memory
  4043. ld e,a ;0dbe Copy drive number to E register
  4044. ld d,000h ;0dbf Clear D register (DE = drive number, 0-3)
  4045. add iy,de ;0dc1 Add drive offset to status table pointer (IY += drive)
  4046. ld a,(01225h) ;0dc3 Load current track number from memory
  4047. cp (iy+000h) ;0dc6 Compare with track in drive status table
  4048. jr z,l0dd1h ;0dc9 Skip seek if already on correct track
  4049. l0dcbh: ; Seek and read retry loop
  4050. push bc ;0dcb Save retry counter on stack
  4051. call sub_0d37h ;0dcc Call disk seek and retry operation
  4052. pop bc ;0dcf Restore retry counter from stack
  4053. ret nc ;0dd0 Return with carry clear if seek failed
  4054. l0dd1h: ; Execute read operation
  4055. push bc ;0dd1 Save retry counter on stack
  4056. call sub_0da9h ;0dd2 Call FDC validation function via IX register
  4057. pop bc ;0dd5 Restore retry counter from stack
  4058. ret c ;0dd6 Return with carry set if validation successful
  4059. push bc ;0dd7 Save retry counter again
  4060. call sub_0b1ch ;0dd8 Call actual disk read operation
  4061. pop bc ;0ddb Restore retry counter
  4062. djnz l0dcbh ;0ddc Decrement retry counter, loop if more attempts remain
  4063. or a ;0dde Clear carry flag (all retries exhausted, read failed)
  4064. ret ;0ddf Return with carry clear indicating failure
  4065. ;==============================================================================
  4066. ; FLOPPY DISK STATUS CHECK ROUTINE (0x0DE0)
  4067. ;==============================================================================
  4068. ; Purpose: Check floppy disk controller status and extract specific status bit
  4069. ; Entry Point: l0de0h - Called from interrupt vector 0x000B and multiple locations
  4070. ;
  4071. ; Function:
  4072. ; - Sends status command (0x04) to floppy controller via ports 0xF0/0xF1
  4073. ; - Reads back status response from floppy controller
  4074. ; - Extracts bit 3 from status (rotated to bit 0)
  4075. ; - Stores extracted bit at memory location 0x1203
  4076. ;
  4077. ; Status bit extracted (original bit 3) likely indicates:
  4078. ; - Drive ready condition, Track 0 detection, Write protect, or Index pulse
  4079. ;
  4080. ; Used as: Interrupt service routine and general floppy status check
  4081. ; Ports: 0xF0 (status), 0xF1 (data), 0xFC (control)
  4082. ;==============================================================================
  4083. l0de0h:
  4084. call sub_0bf2h ;0de0 Call FDC write setup, get status byte in A register
  4085. rrca ;0de3 Rotate right (bit 3 → bit 2)
  4086. rrca ;0de4 Rotate right (bit 2 → bit 1)
  4087. rrca ;0de5 Rotate right (bit 1 → bit 0, original bit 3 now in bit 0)
  4088. and 001h ;0de6 Mask to keep only bit 0 (original FDC status bit 3)
  4089. ld (01203h),a ;0de8 Store extracted status bit at drive status location
  4090. ret ;0deb Return with extracted status bit in A
  4091. ;==============================================================================
  4092. ; DISK FORMAT OPERATION ROUTINE (sub_0dech) - 0x0DEC-0x0E1E
  4093. ;==============================================================================
  4094. ; Purpose: Execute complete disk format operation with FDC command setup
  4095. ; Called by: Format command routines that need to prepare and format tracks
  4096. ;
  4097. ; Operation Sequence:
  4098. ; 1. Check FDC write readiness via sub_0d2eh
  4099. ; 2. Set up FDC command 0x0D (FORMAT TRACK) in command buffer
  4100. ; 3. Configure disk parameters and DMA setup
  4101. ; 4. Execute format operation and wait for completion
  4102. ; 5. Validate completion status and return result
  4103. ;
  4104. ; FDC Command: 0x0D = FORMAT TRACK (formats entire track with sector headers)
  4105. ; Memory: 0x1213=command buffer, 0x124B=operation status, 0x120C=completion status
  4106. ;==============================================================================
  4107. sub_0dech:
  4108. call sub_0d2eh ;0dec Check if FDC is ready for write operations
  4109. ret nc ;0def Return with carry clear if FDC not ready for format
  4110. ld hl,01213h ;0df0 Point HL to FDC command buffer
  4111. ld (hl),00dh ;0df3 Set command byte to 0x0D (FORMAT TRACK command)
  4112. call sub_0c6ah ;0df5 Call disk parameter configuration routine
  4113. call sub_0b7bh ;0df8 Call drive/head selection setup routine
  4114. call sub_0e1fh ;0dfb Call track/sector parameter table setup
  4115. call sub_0ca9h ;0dfe Call DMA controller configuration routine
  4116. call sub_0cbdh ;0e01 Call DMA transfer initialization routine
  4117. xor a ;0e04 Clear A register (A = 0)
  4118. ld (0124bh),a ;0e05 Clear operation status flag (0 = operation in progress)
  4119. ld hl,01213h ;0e08 Point HL to FDC command buffer start
  4120. ld b,006h ;0e0b Set command length to 6 bytes (FORMAT TRACK parameters)
  4121. call l0b64h ;0e0d Transmit 6-byte format command to FDC via port 0xF1
  4122. ret nc ;0e10 Return with carry clear if command transmission failed
  4123. l0e11h: ; Wait for format operation completion
  4124. ld a,(0124bh) ;0e11 Load operation status flag from memory
  4125. or a ;0e14 Test if operation completed (non-zero = done)
  4126. jr z,l0e11h ;0e15 Loop until format operation completes
  4127. ld a,(0120ch) ;0e17 Load FDC completion status register
  4128. l0e1ah: ; Validate format completion status
  4129. and 0c0h ;0e1a Test bits 6&7 (completion and error status flags)
  4130. ret nz ;0e1c Return with non-zero if format errors detected
  4131. scf ;0e1d Set carry flag (format operation successful)
  4132. ret ;0e1e Return with carry set indicating successful format
  4133. ;==============================================================================
  4134. ; FORMAT SECTOR DATA GENERATION ROUTINE (sub_0e1fh) - 0x0E1F-0x0E42
  4135. ;==============================================================================
  4136. ; Purpose: Generate sector data pattern for format track operation
  4137. ; Called by: Format operation routine (sub_0dech) to create sector headers
  4138. ;
  4139. ; Operation:
  4140. ; 1. Call sub_0c7bh to set up track/sector parameter tables
  4141. ; 2. Load drive configuration from memory (drive status, head flags, track)
  4142. ; 3. Set up DMA buffer at 0x1000 for format data generation
  4143. ; 4. Generate 26 sector entries (0x1A = 26 sectors) with format pattern:
  4144. ; - Track number (from 0x1225)
  4145. ; - Head/drive flags (from 0x1226)
  4146. ; - Sector number (incrementing: 1,2,3...26)
  4147. ; - Sector size (from 0x1203)
  4148. ;
  4149. ; Memory Layout: Creates format data at 0x1000+ for FDC FORMAT TRACK command
  4150. ; Format: Each sector = 4 bytes (track, head, sector, size) × 26 sectors = 104 bytes
  4151. ;==============================================================================
  4152. sub_0e1fh:
  4153. call sub_0c7bh ;0e1f Call track/sector parameter table setup routine
  4154. ld a,(01203h) ;0e22 Load drive status/sector size from memory
  4155. ld e,a ;0e25 Store sector size parameter in E register
  4156. ld a,(01226h) ;0e26 Load drive control flags (head selection)
  4157. ld c,a ;0e29 Store head/drive flags in C register
  4158. ld a,(01225h) ;0e2a Load current track number from memory
  4159. ld d,001h ;0e2d Set initial sector number to 1 (first sector)
  4160. ld b,01ah ;0e2f Set loop counter to 0x1A (26 sectors per track)
  4161. ld hl,01000h ;0e31 Point HL to format data buffer at 0x1000
  4162. ld (01200h),hl ;0e34 Store buffer address in DMA address register
  4163. l0e37h: ; Sector format data generation loop
  4164. ld (hl),a ;0e37 Store track number (A) in format buffer
  4165. inc hl ;0e38 Move to next byte in buffer
  4166. ld (hl),c ;0e39 Store head/drive flags (C) in format buffer
  4167. inc hl ;0e3a Move to next byte in buffer
  4168. ld (hl),d ;0e3b Store sector number (D) in format buffer
  4169. inc hl ;0e3c Move to next byte in buffer
  4170. ld (hl),e ;0e3d Store sector size (E) in format buffer
  4171. inc hl ;0e3e Move to next 4-byte sector entry
  4172. inc d ;0e3f Increment sector number (1→2→3...→26)
  4173. djnz l0e37h ;0e40 Decrement sector counter, loop until all 26 sectors done
  4174. ret ;0e42 Return with format data buffer prepared at 0x1000
  4175. ;==============================================================================
  4176. ; COMPLETE DISK FORMAT OPERATION (sub_0e43h) - 0x0E43-0x0E86
  4177. ;==============================================================================
  4178. ; Purpose: Format entire disk with comprehensive drive setup and validation
  4179. ; Called by: System initialization routines for complete disk preparation
  4180. ;
  4181. ; Operation Sequence:
  4182. ; 1. Validate FDC status and drive readiness
  4183. ; 2. Initialize drive status table and perform read test
  4184. ; 3. Format all tracks (0-76, total 77 tracks) with both head configurations
  4185. ; 4. Handle single/double-sided drive detection and formatting
  4186. ;
  4187. ; Track Coverage: Formats tracks 0 through 76 (0x4D-1 = 77 tracks total)
  4188. ; Head Support: Handles both head 0 and head 1 for double-sided drives
  4189. ;==============================================================================
  4190. sub_0e43h:
  4191. call sub_0bf2h ;0e43 Call FDC write setup, get status byte
  4192. xor 020h ;0e46 XOR with 0x20 (flip write ready bit)
  4193. and 060h ;0e48 Test bits 5&6 (data direction and write ready)
  4194. ret nz ;0e4a Return if FDC not ready for format operations
  4195. call l0de0h ;0e4b Call FDC status check, extract drive status bit
  4196. ld iy,01205h ;0e4e Point IY to drive status table base
  4197. ld a,(01202h) ;0e52 Load current drive number (0-3)
  4198. ld e,a ;0e55 Copy drive number to E register
  4199. ld d,000h ;0e56 Clear D register (DE = drive offset)
  4200. add iy,de ;0e58 Point IY to current drive's status entry
  4201. call sub_0b1ch ;0e5a Perform initial drive read test
  4202. ret nc ;0e5d Return if drive read test failed
  4203. xor a ;0e5e Clear A register (start with track 0)
  4204. ld (01225h),a ;0e5f Set starting track number to 0
  4205. l0e62h: ; Main track formatting loop (tracks 0-76)
  4206. call sub_0c05h ;0e62 Call disk seek and status check for current track
  4207. ret nc ;0e65 Return if seek to track failed
  4208. xor a ;0e66 Clear head selection (start with head 0)
  4209. ld (01226h),a ;0e67 Set head selection to 0 (first head)
  4210. call sub_0dech ;0e6a Call format track operation for head 0
  4211. ret nc ;0e6d Return if head 0 format failed
  4212. ld a,(01203h) ;0e6e Load drive capabilities/head count from status
  4213. or a ;0e71 Test if drive supports multiple heads
  4214. jr z,l0e7bh ;0e72 Skip head 1 format if single-sided drive
  4215. ld (01226h),a ;0e74 Set head selection to 1 (second head)
  4216. call sub_0dech ;0e77 Call format track operation for head 1
  4217. ret nc ;0e7a Return if head 1 format failed
  4218. l0e7bh: ; Advance to next track
  4219. ld a,(01225h) ;0e7b Load current track number
  4220. inc a ;0e7e Increment to next track (0→1→2...→76)
  4221. ld (01225h),a ;0e7f Store updated track number
  4222. cp 04dh ;0e82 Compare with 77 (0x4D = total tracks to format)
  4223. jr c,l0e62h ;0e84 Continue formatting if more tracks remain
  4224. jp sub_0b1ch ;0e86 Final drive validation read after complete format
  4225. ;==============================================================================
  4226. ; SYSTEM DIAGNOSTIC AND HARDWARE TEST SUITE (sub_0e89h) - 0x0E89-0x0EA1
  4227. ;==============================================================================
  4228. ; Purpose: Comprehensive system hardware testing and validation
  4229. ; Called by: System initialization to verify all hardware components
  4230. ;
  4231. ; Test Sequence:
  4232. ; 1. RAM memory boundary detection and testing
  4233. ; 2. Extended system component validation
  4234. ; 3. FDC initialization and drive testing
  4235. ; 4. Additional hardware subsystem verification
  4236. ;
  4237. ; Returns: Various status codes from individual test routines
  4238. ;==============================================================================
  4239. sub_0e89h:
  4240. call sub_0ea2h ;0e89 Call RAM memory diagnostic test
  4241. call nz,sub_0f6bh ;0e8c If RAM test indicates issues, call error handler
  4242. call sub_0ecch ;0e8f Call extended system component test
  4243. call nz,sub_0f70h ;0e92 If system test fails, call failure handler
  4244. call sub_0a8dh ;0e95 Call FDC initialization and drive setup
  4245. call nc,sub_0f75h ;0e98 If FDC init fails, call initialization error handler
  4246. call sub_0f10h ;0e9b Call additional hardware subsystem test
  4247. call nz,sub_0f7ah ;0e9e If hardware test fails, call diagnostic error handler
  4248. ret ;0ea1 Return from complete system diagnostic suite
  4249. ;==============================================================================
  4250. ; RAM MEMORY DIAGNOSTIC TEST (0x0EA2)
  4251. ;==============================================================================
  4252. ; Purpose: Test available RAM and detect memory boundaries
  4253. ; Tests RAM starting from 0x1400 (above 1KB base RAM) to find additional memory
  4254. ;
  4255. ; Memory Layout:
  4256. ; - 0x0000-0x0FFF: EPROM
  4257. ; - 0x1000-0x13FF: Base 1KB RAM (1024 bytes)
  4258. ; - 0x1400+: Extended RAM (if present) or memory-mapped I/O
  4259. ;
  4260. ; Test Method:
  4261. ; - Starts at 0x1400 (beyond base 1KB RAM)
  4262. ; - Tests each location with multiple bit patterns
  4263. ; - Continues until test fails (indicating no more RAM or different hardware)
  4264. ;
  4265. ; Purpose: Detect extended RAM modules or memory-mapped peripherals
  4266. ; Returns: Z flag clear when memory boundary reached, Z set if wraps to 0x0000
  4267. ;==============================================================================
  4268. sub_0ea2h:
  4269. ld de,l0000h ;0ea2 Set DE = 0x0000 (used for wrap-around detection)
  4270. ld hl,01400h ;0ea5 Start at 0x1400 (beyond 1KB base RAM)
  4271. ; Test each memory location above base RAM
  4272. l0ea8h:
  4273. call sub_0eb3h ;0ea8 Test current memory location with bit patterns
  4274. ret nz ;0eab Return when memory test fails (found boundary)
  4275. inc hl ;0eac Move to next higher memory address
  4276. sbc hl,de ;0ead Check if wrapped around to 0x0000
  4277. add hl,de ;0eaf Restore HL value
  4278. jr nz,l0ea8h ;0eb0 Continue until boundary found or wrap-around
  4279. ret ;0eb2 Return if wrapped to 0x0000 (full 64K RAM)
  4280. ;==============================================================================
  4281. ; MEMORY LOCATION TEST WITH MULTIPLE PATTERNS (0x0EB3)
  4282. ;==============================================================================
  4283. ; Purpose: Test single memory location with all bit patterns from test table
  4284. ; Input: HL = memory address to test
  4285. ;
  4286. ; Test Procedure:
  4287. ; 1. Load test pattern count and pattern table pointer
  4288. ; 2. For each pattern: save original data, write pattern, read back, verify
  4289. ; 3. Restore original data, test next pattern
  4290. ; 4. Interrupts disabled during write/read/verify to prevent corruption
  4291. ;
  4292. ; Test Patterns (at l0ec9h):
  4293. ; - 0x02: Tests bit 1 (and others as 0)
  4294. ; - 0x55: Alternating bits pattern (01010101)
  4295. ; - 0xAA: Inverse alternating pattern (10101010)
  4296. ;
  4297. ; Returns: Z flag set if all patterns pass, Z clear if any pattern fails
  4298. ;==============================================================================
  4299. sub_0eb3h:
  4300. ld ix,l0ec9h ;0eb3 Point IX to test pattern table
  4301. ld b,(ix+000h) ;0eb7 Load pattern count (first byte of table)
  4302. ; Test each pattern from the table
  4303. l0ebah:
  4304. inc ix ;0eba Advance to next test pattern
  4305. ld a,(ix+000h) ;0ebc Load test pattern into A
  4306. ld c,(hl) ;0ebf Save original memory contents in C
  4307. di ;0ec0 Disable interrupts (critical memory test section)
  4308. ld (hl),a ;0ec1 Write test pattern to memory
  4309. cp (hl) ;0ec2 Read back and compare with expected pattern
  4310. ld (hl),c ;0ec3 Restore original memory contents
  4311. ei ;0ec4 Re-enable interrupts
  4312. ret nz ;0ec5 Return with error if pattern didn't match
  4313. djnz l0ebah ;0ec6 Test next pattern (decrement B, loop if not zero)
  4314. ret ;0ec8 Return with Z set (all patterns passed)
  4315. ;==============================================================================
  4316. ; MEMORY TEST PATTERN TABLE (0x0EC9)
  4317. ;==============================================================================
  4318. ; Format: [Count] [Pattern1] [Pattern2] [Pattern3]
  4319. ; These patterns test different failure modes:
  4320. ; - 0x02: Tests if bit 1 can be set while others stay clear
  4321. ; - 0x55: Tests alternating bit pattern (detects adjacent bit interference)
  4322. ; - 0xAA: Inverse alternating (detects stuck bits and crosstalk)
  4323. ;==============================================================================
  4324. l0ec9h:
  4325. defb 0x03 ;0ec9 Number of test patterns
  4326. defb 0x55 ;0eca Test pattern 1: 01010101 (alternating bits)
  4327. defb 0xAA ;0ecb Test pattern 2: 10101010 (inverse alternating)
  4328. ;==============================================================================
  4329. ; INTERRUPT VECTOR TABLE INITIALIZATION (0x0ECC)
  4330. ;==============================================================================
  4331. ; Purpose: Set up interrupt vector table and perform peripheral testing
  4332. ; This routine initializes the interrupt mode 2 vector table with error
  4333. ; handlers and tests peripheral chips through port operations.
  4334. ;
  4335. ; Interrupt Vector Setup:
  4336. ; Sets addresses 0x1330, 0x1332, 0x1334, 0x1336 to point to l0f3fh
  4337. ; These are interrupt vector table entries for IM2 mode interrupts
  4338. ;
  4339. ; Peripheral Testing:
  4340. ; Tests ports 0xF4 through 0xF7 with specific control sequences
  4341. ; Uses port commands 0x30 (initialize) and 0x03 (test/verify)
  4342. ; Validates peripheral response through status flag at 0x1103
  4343. ;==============================================================================
  4344. sub_0ecch:
  4345. ld hl,l0f3fh ;0ecc ; Load address of interrupt error handler
  4346. ld (01330h),hl ;0ecf ; Set interrupt vector table entry 0
  4347. ld (01332h),hl ;0ed2 ; Set interrupt vector table entry 1
  4348. ld (01334h),hl ;0ed5 ; Set interrupt vector table entry 2
  4349. ld (01336h),hl ;0ed8 ; Set interrupt vector table entry 3
  4350. ld c,0f4h ;0edb ; Start with port 0xF4 (first peripheral port)
  4351. ld a,030h ;0edd ; Load initialization command (0x30)
  4352. out (c),a ;0edf ; Send initialization command to peripheral
  4353. ;==============================================================================
  4354. ; PERIPHERAL PORT TESTING LOOP (0x0EE1)
  4355. ;==============================================================================
  4356. ; Purpose: Test peripheral chips at ports 0xF4-0xF7 for proper response
  4357. ; Tests each port with initialization and verification commands
  4358. ;==============================================================================
  4359. l0ee1h:
  4360. ld a,0ffh ;0ee1 ; Set error flag (assume failure initially)
  4361. ld (01103h),a ;0ee3 ; Store error flag in status location
  4362. call sub_0f01h ;0ee6 ; Send command sequence to current peripheral
  4363. push bc ;0ee9 ; Save current port number
  4364. ld bc,01900h ;0eea ; Load delay count (6400 cycles for peripheral response)
  4365. call sub_0f0ah ;0eed ; Wait for peripheral to process command
  4366. pop bc ;0ef0 ; Restore current port number
  4367. ld a,003h ;0ef1 ; Load verification command (0x03)
  4368. out (c),a ;0ef3 ; Send verification command to peripheral
  4369. ld a,(01103h) ;0ef5 ; Read status flag after peripheral operation
  4370. or a ;0ef8 ; Test if peripheral responded correctly (0=success)
  4371. ret nz ;0ef9 ; Return if peripheral failed to respond
  4372. inc c ;0efa ; Move to next peripheral port (0xF4→0xF5→0xF6→0xF7)
  4373. ld a,c ;0efb ; Check current port number
  4374. cp 0f8h ;0efc ; Compare with end limit (0xF8 = beyond 0xF7)
  4375. jr nz,l0ee1h ;0efe ; Continue testing if more ports remain
  4376. ret ;0f00 ; Return with success (all peripherals tested)
  4377. ;==============================================================================
  4378. ; PERIPHERAL COMMAND SEQUENCE (0x0F01)
  4379. ;==============================================================================
  4380. ; Purpose: Send specific command sequence to peripheral chip
  4381. ; Sends initialization commands to configure peripheral for testing
  4382. ;==============================================================================
  4383. sub_0f01h:
  4384. ld a,028h ;0f01 ; Load parameter value (0x28 = timing/mode setting)
  4385. ld b,087h ;0f03 ; Load command value (0x87 = control command)
  4386. out (c),b ;0f05 ; Send control command to peripheral
  4387. out (c),a ;0f07 ; Send parameter value to peripheral
  4388. ret ;0f09 ; Return after command sequence complete
  4389. ; --------------------------------------------------
  4390. ; sub_0f0ah: Wait/Delay Loop
  4391. ; Burns CPU cycles by decrementing BC until it reaches zero.
  4392. ; Used for timing delays, hardware settling, or pacing init steps.
  4393. ; Entry: BC = delay value
  4394. ; Exit: BC = 0
  4395. ; No hardware interaction, pure software delay
  4396. ; --------------------------------------------------
  4397. sub_0f0ah:
  4398. dec bc ;0f0a
  4399. ld a,c ;0f0b
  4400. or b ;0f0c
  4401. jr nz,sub_0f0ah ;0f0d
  4402. ret ;0f0f
  4403. ; --------------------------------------------------
  4404. ; sub_0f10h: Hardware Initialization & Memory Test Routine
  4405. ; - Clears accumulator and sets 01204h to 0
  4406. ; - Sets up pointer at 0133ch to l0f48h
  4407. ; - Sets 01103h to 0xFF (error/status flag)
  4408. ; - Calls setup_peripherals_01a1h with l0f55h (hardware setup)
  4409. ; - Waits using delay loop (sub_0f0ah, BC=0x1000)
  4410. ; - If 01103h is nonzero, returns (error)
  4411. ; - If zero, compares 256 bytes at HL and DE (memory test), returns if mismatch
  4412. ; Called at 0e9b as part of system initialization/test sequence
  4413. ; --------------------------------------------------
  4414. ;==============================================================================
  4415. ; MEMORY TEST AND HARDWARE INITIALIZATION (0x0F10)
  4416. ;==============================================================================
  4417. ; Purpose: Comprehensive RAM test comparing ROM shadow with actual RAM
  4418. ; This routine performs a critical memory integrity test by comparing the
  4419. ; first 256 bytes of ROM (0x0000-0x00FF) with corresponding RAM locations
  4420. ; (0x1000-0x10FF) to verify RAM is functioning correctly.
  4421. ;
  4422. ; Test Strategy:
  4423. ; 1. Initialize hardware peripherals and interrupt handlers
  4424. ; 2. Set up error detection mechanisms
  4425. ; 3. Allow hardware to stabilize with timing delay
  4426. ; 4. Perform byte-by-byte comparison between ROM and RAM
  4427. ; 5. Return status indicating memory integrity
  4428. ;
  4429. ; Memory Locations Used:
  4430. ; • 0x1204: Test control flags (0=test mode, 1=normal operation)
  4431. ; • 0x133C: Interrupt vector pointer (set to 0x0F48)
  4432. ; • 0x1103: Error status flag (0xFF=error, 0x00=success)
  4433. ;
  4434. ; Hardware Integration:
  4435. ; • Configures peripheral hardware via setup_peripherals_01a1h
  4436. ; • Sets up interrupt handling for test environment
  4437. ; • Uses timing delays to ensure hardware stability
  4438. ;
  4439. ; Returns:
  4440. ; • Zero flag set: Memory test passed, RAM integrity verified
  4441. ; • Zero flag clear: Memory test failed, RAM fault detected
  4442. ;==============================================================================
  4443. sub_0f10h:
  4444. xor a ;0f10 ; Clear accumulator (A = 0)
  4445. ld (01204h),a ;0f11 ; Set test control flag to 0 (enable test mode)
  4446. ld hl,l0f48h ;0f14 ; Load address of interrupt service routine
  4447. ld (0133ch),hl ;0f17 ; Set interrupt vector pointer for test environment
  4448. dec a ;0f1a ; Set A = 0xFF (error flag value)
  4449. ld (01103h),a ;0f1b ; Initialize error status to 0xFF (assume error initially)
  4450. ld hl,l0f55h ;0f1e ; Load address of hardware configuration data
  4451. call setup_peripherals_01a1h ;0f21 ; Initialize peripheral hardware and interrupts
  4452. ld bc,01000h ;0f24 ; Load delay count (4096 iterations for hardware stabilization)
  4453. call sub_0f0ah ;0f27 ; Execute timing delay loop (allow hardware to settle)
  4454. ld a,(01103h) ;0f2a ; Read error status flag after hardware initialization
  4455. or a ;0f2d ; Test if error flag is non-zero
  4456. ret nz ;0f2e ; Return immediately if hardware initialization failed
  4457. ;==============================================================================
  4458. ; RAM INTEGRITY TEST - ROM vs RAM COMPARISON (0x0F2F)
  4459. ;==============================================================================
  4460. ; Performs byte-by-byte comparison between ROM (0x0000-0x00FF) and
  4461. ; RAM (0x1000-0x10FF) to verify RAM is correctly mirroring ROM data.
  4462. ; This test validates that the memory system is functioning properly.
  4463. ;==============================================================================
  4464. ld hl,01000h ;0f2f ; Point to start of RAM test area (0x1000)
  4465. ld de,l0000h ;0f32 ; Point to start of ROM reference area (0x0000)
  4466. ld b,0ffh ;0f35 ; Set counter for 255 bytes (256 total with DJNZ behavior)
  4467. l0f37h:
  4468. ld a,(de) ;0f37 ; Load byte from ROM (reference data)
  4469. cp (hl) ;0f38 ; Compare with corresponding byte in RAM
  4470. ret nz ;0f39 ; Return immediately if mismatch found (memory fault)
  4471. inc hl ;0f3a ; Move to next RAM address
  4472. inc de ;0f3b ; Move to next ROM address
  4473. djnz l0f37h ;0f3c ; Continue until all 256 bytes tested
  4474. ret ;0f3e ; Return with zero flag set (test passed)
  4475. ;==============================================================================
  4476. ; INTERRUPT SERVICE ROUTINE - ERROR HANDLER (0x0F3F)
  4477. ;==============================================================================
  4478. ; Purpose: Generic interrupt service routine for error handling during hardware tests
  4479. ; This routine is installed in multiple interrupt vector table entries to catch
  4480. ; any unexpected interrupts that occur during hardware initialization and testing.
  4481. ;
  4482. ; Called from: Interrupt vector table entries at 0x1330, 0x1332, 0x1334, 0x1336
  4483. ; Used during: Hardware initialization, FDC operations, and system testing
  4484. ;
  4485. ; Operation:
  4486. ; 1. Save processor state (AF register)
  4487. ; 2. Clear error status flag (mark as successful)
  4488. ; 3. Restore processor state
  4489. ; 4. Return from interrupt with interrupts enabled
  4490. ;
  4491. ; Function: Provides safe interrupt handling during critical hardware operations
  4492. ; This prevents system crashes if unexpected interrupts occur during testing.
  4493. ;==============================================================================
  4494. l0f3fh:
  4495. push af ;0f3f ; Save accumulator and flags on stack
  4496. ;==============================================================================
  4497. ; INTERRUPT COMPLETION HANDLER (0x0F40)
  4498. ;==============================================================================
  4499. ; Purpose: Common completion path for interrupt service routines
  4500. ; Clears error status and returns from interrupt with proper state restoration.
  4501. ;==============================================================================
  4502. l0f40h:
  4503. xor a ;0f40 ; Clear accumulator (A = 0)
  4504. ld (01103h),a ;0f41 ; Clear error status flag (0 = success, no error)
  4505. pop af ;0f44 ; Restore accumulator and flags from stack
  4506. ei ;0f45 ; Enable interrupts (standard RETI behavior)
  4507. reti ;0f46 ; Return from interrupt (pops PC and restores state)
  4508. ;==============================================================================
  4509. ; SPECIALIZED INTERRUPT HANDLER WITH PORT OPERATIONS (0x0F48)
  4510. ;==============================================================================
  4511. ; Purpose: Interrupt service routine that performs port I/O operations
  4512. ; This appears to be a hardware-specific interrupt handler that sends data
  4513. ; to port 0xFC during interrupt processing, possibly for peripheral control.
  4514. ;
  4515. ; Port Operations:
  4516. ; • Sends 0xC3 to port 0xFC six times in sequence
  4517. ; • Port 0xFC likely controls DMA, FDC, or other peripheral hardware
  4518. ; • Multiple writes may be required for hardware sequencing
  4519. ;
  4520. ; Used by: Hardware initialization routine (pointed to by interrupt vector)
  4521. ; Context: Called during peripheral setup and hardware testing phases
  4522. ;==============================================================================
  4523. l0f48h:
  4524. push af ;0f48 ; Save accumulator and flags
  4525. push bc ;0f49 ; Save BC register pair
  4526. ld a,0c3h ;0f4a ; Load control value 0xC3 for port operation
  4527. ld b,006h ;0f4c ; Set counter for 6 iterations
  4528. l0f4eh:
  4529. out (0fch),a ;0f4e ; Send DMA command 0xC3 to Z80 DMA controller
  4530. ; ; 0xC3 = DMA reset/initialization command
  4531. ; ; Repeated 6 times for proper DMA controller reset
  4532. djnz l0f4eh ;0f50 ; Repeat 6 times (decrement B, loop if not zero)
  4533. pop bc ;0f52 ; Restore BC register pair
  4534. jr l0f40h ;0f53 ; Jump to common interrupt completion routine
  4535. ;==============================================================================
  4536. ; HARDWARE CONFIGURATION DATA TABLE (0x0F55)
  4537. ;==============================================================================
  4538. ; Purpose: Configuration data for peripheral hardware initialization
  4539. ; Used by: setup_peripherals_01a1h routine during system initialization
  4540. ; Format: Binary configuration data for DMA setup
  4541. ;
  4542. ; This table contains the initialization parameters and control sequences
  4543. ; required to properly configure the Z80 peripheral hardware during boot.
  4544. ; The data is processed by the hardware setup routine to configure:
  4545. ; • Z80 DMA controller transfer parameters
  4546. ;
  4547. ; TABLE FORMAT: [byte_count] [port_address] [data_bytes...]
  4548. ; • 0x13 (19 decimal) = total byte count for this configuration block
  4549. ; • 0xFC = Z80 DMA controller port address
  4550. ; • Following 19 bytes = DMA initialization sequence written to port 0xFC
  4551. ;==============================================================================
  4552. l0f55h:
  4553. defb 0x13 ;0f55 Byte count: 19 bytes total (1 count + 18 DMA init bytes)
  4554. defb 0xfc ;0f56 Target port: 0xFC (Z80 DMA controller)
  4555. defb 0x79 ;0f57 DMA WR0: Base register, transfer mode (Block transfer, A→B)
  4556. defb 0x00 ;0f58 DMA WR1: Port A starting address LOW byte
  4557. defb 0x00 ;0f59 DMA WR2: Port A starting address HIGH byte
  4558. defb 0xfe ;0f5a DMA WR0: Port A address LOW (0xFE = FDC data port region)
  4559. defb 0x00 ;0f5b DMA WR1: Port A address HIGH byte
  4560. defb 0x10 ;0f5c DMA WR2: Block length LOW byte (16 bytes)
  4561. defb 0x14 ;0f5d DMA WR3: Block length HIGH + control
  4562. defb 0xdb ;0f5e DMA WR4: Port B starting address LOW byte
  4563. defb 0x00 ;0f5f DMA WR5: Port B starting address HIGH byte
  4564. defb 0x10 ;0f60 DMA WR0: Port B address configuration
  4565. defb 0x12 ;0f61 DMA WR1: Port B control (memory increment mode)
  4566. defb 0x3c ;0f62 DMA WR2: Interrupt control and timing
  4567. defb 0x82 ;0f63 DMA WR3: Interrupt vector base
  4568. defb 0xcf ;0f64 DMA WR4: Pulse control (Ready/Wait signal timing)
  4569. defb 0x05 ;0f65 DMA WR5: Command register (Enable DMA, continuous mode)
  4570. defb 0xcf ;0f66 DMA WR6: Additional control flags
  4571. defb 0xb3 ;0f67 DMA command: Load and enable DMA operation
  4572. defb 0xab ;0f68 DMA command: Configure interrupt and ready modes
  4573. defb 0x87 ;0f69 DMA command: Enable DMA transfer operation
  4574. defb 0x00 ;0f6a Configuration terminator: 0x00
  4575. ;==============================================================================
  4576. ; ERROR MESSAGE DISPLAY ROUTINES (0x0F6B-0x0F7F)
  4577. ;==============================================================================
  4578. ; Purpose: Display specific error messages for hardware failures
  4579. ; These routines set HL to point to error message strings and call the
  4580. ; standard print routine at l00fdh to display them to the console.
  4581. ;
  4582. ; Error Messages:
  4583. ; • sub_0f6bh: "MEM ERR" - Memory error detected
  4584. ; • sub_0f70h: "FLOPPY CTC ERR" - Floppy controller CTC timing error
  4585. ; • sub_0f75h: "FLOPPY NEC ERR" - NEC µPD765A FDC hardware error
  4586. ; • sub_0f7ah: "DMA ERR" - Z80 DMA controller error (also sets drive flag)
  4587. ;==============================================================================
  4588. sub_0f6bh:
  4589. ld hl,l0f85h ;0f6b ; Point to "MEM ERR" message
  4590. jr l0f82h ;0f6e ; Jump to common print routine
  4591. sub_0f70h:
  4592. ld hl,l0f8fh ;0f70 ; Point to "FLOPPY CTC ERR" message
  4593. jr l0f82h ;0f73 ; Jump to common print routine
  4594. sub_0f75h:
  4595. ld hl,l0fa0h ;0f75 ; Point to "FLOPPY NEC ERR" message
  4596. jr l0f82h ;0f78 ; Jump to common print routine
  4597. sub_0f7ah:
  4598. ld a,001h ;0f7a ; Set error flag value
  4599. ld (01204h),a ;0f7c ; Store in drive status location (mark DMA error)
  4600. ld hl,l0fb1h ;0f7f ; Point to "DMA ERR" message
  4601. l0f82h:
  4602. jp l00fdh ;0f82 ; Call standard string print routine
  4603. ;==============================================================================
  4604. ; ERROR MESSAGE STRINGS (0x0F85-0x0FBA)
  4605. ;==============================================================================
  4606. ; Null-terminated error message strings displayed by the error routines above.
  4607. ; Each message includes CR/LF for proper console formatting.
  4608. ;
  4609. ; Messages:
  4610. ; • l0f85h: "MEM ERR" - Memory subsystem error
  4611. ; • l0f8fh: "FLOPPY CTC ERR" - CTC timing error for floppy operations
  4612. ; • l0fa0h: "FLOPPY NEC ERR" - NEC µPD765A FDC hardware error
  4613. ; • l0fb1h: "DMA ERR" - Z80 DMA controller error
  4614. ;==============================================================================
  4615. l0f85h: ; "MEM ERR" message
  4616. defb 0x4d ;0f85 'M'
  4617. defb 0x45 ;0f86 'E'
  4618. defb 0x4d ;0f87 'M'
  4619. defb 0x20 ;0f88 ' '
  4620. defb 0x45 ;0f89 'E'
  4621. defb 0x52 ;0f8a 'R'
  4622. defb 0x52 ;0f8b 'R'
  4623. defb 0x0d ;0f8c <CR>
  4624. defb 0x0a ;0f8d <LF>
  4625. defb 0x00 ;0f8e <NUL>
  4626. l0f8fh:
  4627. defb 0x46 ;0f8f 'F'
  4628. defb 0x4c ;0f90 'L'
  4629. defb 0x4f ;0f91 'O'
  4630. defb 0x50 ;0f92 'P'
  4631. defb 0x50 ;0f93 'P'
  4632. defb 0x59 ;0f94 'Y'
  4633. defb 0x20 ;0f95 ' '
  4634. defb 0x43 ;0f96 'C'
  4635. defb 0x54 ;0f97 'T'
  4636. defb 0x43 ;0f98 'C'
  4637. defb 0x20 ;0f99 ' '
  4638. defb 0x45 ;0f9a 'E'
  4639. defb 0x52 ;0f9b 'R'
  4640. defb 0x52 ;0f9c 'R'
  4641. defb 0x0d ;0f9d <CR>
  4642. defb 0x0a ;0f9e <LF>
  4643. defb 0x00 ;0f9f <NUL>
  4644. l0fa0h:
  4645. defb 0x46 ;0fa0 'F'
  4646. defb 0x4c ;0fa1 'L'
  4647. defb 0x4f ;0fa2 'O'
  4648. defb 0x50 ;0fa3 'P'
  4649. defb 0x50 ;0fa4 'P'
  4650. defb 0x59 ;0fa5 'Y'
  4651. defb 0x20 ;0fa6 ' '
  4652. defb 0x4e ;0fa7 'N'
  4653. defb 0x45 ;0fa8 'E'
  4654. defb 0x43 ;0fa9 'C'
  4655. defb 0x20 ;0faa ' '
  4656. defb 0x45 ;0fab 'E'
  4657. defb 0x52 ;0fac 'R'
  4658. defb 0x52 ;0fad 'R'
  4659. defb 0x0d ;0fae <CR>
  4660. defb 0x0a ;0faf <LF>
  4661. defb 0x00 ;0fb0 <NUL>
  4662. l0fb1h:
  4663. defb 0x44 ;0fb1 'D'
  4664. defb 0x4d ;0fb2 'M'
  4665. defb 0x41 ;0fb3 'A'
  4666. defb 0x20 ;0fb4 ' '
  4667. defb 0x45 ;0fb5 'E'
  4668. defb 0x52 ;0fb6 'R'
  4669. defb 0x52 ;0fb7 'R'
  4670. defb 0x0d ;0fb8 <CR>
  4671. defb 0x0a ;0fb9 <LF>
  4672. defb 0x00 ;0fba <NUL>
  4673. l0fbbh:
  4674. xor a ;0fbb Clear A register (A = 0)
  4675. ld (01226h),a ;0fbc Clear drive control flags
  4676. ld (01202h),a ;0fbf Set current drive number to 0 (start with drive A:)
  4677. ld (01225h),a ;0fc2 Clear drive parameter/selector
  4678. inc a ;0fc5 A = 1
  4679. ld (01227h),a ;0fc6 Enable drive operations (1 = enabled)
  4680. call l0de0h ;0fc9 Initialize FDC and check drive status
  4681. ld hl,01000h ;0fcc Set boot load address to 0x1000
  4682. l0fcfh:
  4683. ld (01200h),hl ;0fcf Store DMA/buffer address for disk operations
  4684. call l0dabh ;0fd2 Attempt to read boot sector from current drive
  4685. jp c,01000h ;0fd5
  4686. ld hl,l0fe1h ;0fd8
  4687. call l00fdh ;0fdb
  4688. jp l0294h ;0fde
  4689. l0fe1h:
  4690. defb 0x42 ;0fe1 'B'
  4691. defb 0x4f ;0fe2 'O'
  4692. defb 0x4f ;0fe3 'O'
  4693. defb 0x54 ;0fe4 'T'
  4694. defb 0x20 ;0fe5 ' '
  4695. defb 0x45 ;0fe6 'E'
  4696. defb 0x52 ;0fe7 'R'
  4697. defb 0x52 ;0fe8 'R'
  4698. defb 0x0d ;0fe9 <CR>
  4699. defb 0x0a ;0fea <LF>
  4700. defb 0x00 ;0feb <NUL>
  4701. l0fec: ; VERSION STRING - Displayed during system initialization
  4702. defb 0x56 ;0fec 'V'
  4703. defb 0x65 ;0fed 'e'
  4704. defb 0x72 ;0fee 'r'
  4705. defb 0x20 ;0fef ' '
  4706. defb 0x31 ;0ff0 '1'
  4707. l0ff1h:
  4708. defb 0x2e ;0ff1 '.'
  4709. defb 0x32 ;0ff2 '2'
  4710. defb 0x78 ;0ff3 'x'
  4711. defb 0x20 ;0ff4 ' '
  4712. defb 0x38 ;0ff5 '8'
  4713. l0ff6h:
  4714. defb 0x20 ;0ff6 ' '
  4715. defb 0x69 ;0ff7 'i'
  4716. defb 0x6e ;0ff8 'n'
  4717. defb 0x63 ;0ff9 'c'
  4718. defb 0x68 ;0ffa 'h'
  4719. l0ffbh:
  4720. defb 0x0d ;0ffb <CR>
  4721. defb 0x0a ;0ffc <LF>
  4722. defb 0x0a ;0ffd <LF>
  4723. defb 0x00 ;0ffe <NUL> - String terminator for print routine
  4724. defb 0xff ;0ffe FF