disasm_with_labels.asm 169 KB

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